Creating a custom marker control

Jun 17, 2011 at 8:26 PM

I'm new to Silverlight/WPF and would like to augment the given MediaMarker/MarkerControl to have additional features. From what I understand, I would like to construct a class that inherits MediaMarker or TimelineMediaMarker and add some functionality. I would also like to create a new user control that inherits from MarkerControl and also add some behaviors there. Then I would take the given SMFPlayer modify it's ItemsTemplate/ControlTemplate/ItemsPanel/etc. to use these new classes. Is this possible?

Feb 21, 2012 at 4:59 PM

Hello,

I´d achieved it with:

[TemplateVisualState(Name = "timelinecustom", GroupName = "MarkerTypes")]
public class MarkerControlCustom: MarkerControl
{

}
public class CustomMarker: TimelineMediaMarker
{
    
}
<Core:MarkerItemsControl Grid.ColumnSpan="3" Grid.Column="0" EndPosition="{TemplateBinding EndPosition}" IsLive="{TemplateBinding IsLive}" ItemsSource="{TemplateBinding Markers}" LivePosition="{TemplateBinding LivePosition}" RenderTransformOrigin="0.5,0.5" StartPosition="{TemplateBinding StartPosition}" ThumbWidth="{Binding Width, ElementName=HorizontalThumb}" ItemTemplate="{StaticResource DataTemplateCustom}"/>

<Style x:Key="MarkerControlCustom" TargetType="local:MarkerControlCustom">
        	<Setter Property="Template">
        		<Setter.Value>
        			<ControlTemplate TargetType="Core:MarkerControl">
        				<Grid x:Name="grid" HorizontalAlignment="Center" Height="7" RenderTransformOrigin="0.5,0.5" ToolTipService.ToolTip="{Binding Content}" VerticalAlignment="Bottom" Width="7">
        					<Grid.Projection>
        						<PlaneProjection/>
        					</Grid.Projection>
        					<Grid.RenderTransform>
        						<CompositeTransform/>
        					</Grid.RenderTransform>
        					<VisualStateManager.VisualStateGroups>
        						<VisualStateGroup x:Name="CommonStates">
        							<VisualState x:Name="Normal"/>
        							<VisualState x:Name="StateMouseOver"/>
        						</VisualStateGroup>
        						<VisualStateGroup x:Name="MarkerTypes">
        							<VisualState x:Name="timeline">
        								<Storyboard>
        									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="timeline_path">
        										<DiscreteObjectKeyFrame KeyTime="0">
        											<DiscreteObjectKeyFrame.Value>
        												<Visibility>Visible</Visibility>
        											</DiscreteObjectKeyFrame.Value>
        										</DiscreteObjectKeyFrame>
        									</ObjectAnimationUsingKeyFrames>
        								</Storyboard>
        							</VisualState>
                                    <VisualState x:Name="timelinecustom">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="timelinecustom_path">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="chapter">
        								<Storyboard>
        									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="rectangle">
        										<DiscreteObjectKeyFrame KeyTime="0">
        											<DiscreteObjectKeyFrame.Value>
        												<Visibility>Visible</Visibility>
        											</DiscreteObjectKeyFrame.Value>
        										</DiscreteObjectKeyFrame>
        									</ObjectAnimationUsingKeyFrames>
        								</Storyboard>
        							</VisualState>
        						</VisualStateGroup>
        					</VisualStateManager.VisualStateGroups>
        					<Path x:Name="timeline_path" Data="M0.044930875,0.044930875 L0.044930875,13.928502 L14.310663,0.067577466 z" Fill="#FF8DE6FC" HorizontalAlignment="Left" Height="7" Margin="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#FF2A2A2A" StrokeThickness="0.5" UseLayoutRounding="False" Visibility="Collapsed" VerticalAlignment="Top" Width="7" d:LayoutOverrides="HorizontalMargin">
        						<Path.RenderTransform>
        							<CompositeTransform TranslateY="-8"/>
        						</Path.RenderTransform>
        					</Path>
                            <Path x:Name="timelinecustom_path" Data="M0.044930875,0.044930875 L0.044930875,13.928502 L14.310663,0.067577466 z" Fill="Red" HorizontalAlignment="Left" Height="7" Margin="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#FF2A2A2A" StrokeThickness="0.5" UseLayoutRounding="False" Visibility="Collapsed" VerticalAlignment="Top" Width="7" d:LayoutOverrides="HorizontalMargin">
                                <Path.RenderTransform>
                                    <CompositeTransform TranslateY="-8"/>
                                </Path.RenderTransform>
                            </Path>
                            <Rectangle x:Name="rectangle" Fill="White" Height="5" Opacity="0.6" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5" Visibility="Collapsed" Width="1">
        						<Rectangle.RenderTransform>
        							<CompositeTransform TranslateY="-1"/>
        						</Rectangle.RenderTransform>
        					</Rectangle>
        				</Grid>
        			</ControlTemplate>
                </Setter.Value>
        	</Setter>
        </Style>
        <DataTemplate x:Key="DataTemplateCustom">
        	<local:MarkerControlCustom HorizontalAlignment="Left" VerticalAlignment="Top" Style="{StaticResource MarkerControlCustom}" d:IsHidden="True" >
        	</local:MarkerControlCustom>
        </DataTemplate>
<!-- <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Core:MarkerControl"> <Grid x:Name="grid" HorizontalAlignment="Center" Height="7" RenderTransformOrigin="0.5,0.5" ToolTipService.ToolTip="{Binding Content}" VerticalAlignment="Bottom" Width="7"> <Grid.Projection> <PlaneProjection /> </Grid.Projection> <Grid.RenderTransform> <CompositeTransform /> </Grid.RenderTransform> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="StateMouseOver" /> </VisualStateGroup> <VisualStateGroup x:Name="MarkerTypes"> <VisualState x:Name="timeline"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="timeline_path"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="timelinecustom"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="timelinecustom_path"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="chapter"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="rectangle"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Path x:Name="timeline_path" Data="M0.044930875,0.044930875 L0.044930875,13.928502 L14.310663,0.067577466 z" Fill="#FF8DE6FC" HorizontalAlignment="Left" Height="7" Margin="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#FF2A2A2A" StrokeThickness="0.5" UseLayoutRounding="False" Visibility="Collapsed" VerticalAlignment="Top" Width="7" d:LayoutOverrides="HorizontalMargin"> <Path.RenderTransform> <CompositeTransform TranslateY="-8" /> </Path.RenderTransform> </Path> <Path x:Name="timelinecustom_path" Data="M0.044930875,0.044930875 L0.044930875,13.928502 L14.310663,0.067577466 z" Fill="Red" HorizontalAlignment="Left" Height="7" Margin="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#FF2A2A2A" StrokeThickness="0.5" UseLayoutRounding="False" Visibility="Collapsed" VerticalAlignment="Top" Width="7" d:LayoutOverrides="HorizontalMargin"> <Path.RenderTransform> <CompositeTransform TranslateY="-8" /> </Path.RenderTransform> </Path> <Rectangle x:Name="rectangle" Fill="White" Height="5" Opacity="0.6" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5" Visibility="Collapsed" Width="1"> <Rectangle.RenderTransform> <CompositeTransform TranslateY="-1" /> </Rectangle.RenderTransform> </Rectangle> </Grid> </ControlTemplate> </Setter.Value> </Setter> -->


<!--
        	<Setter Property="Template">
        		<Setter.Value>
        			<ControlTemplate TargetType="Core:MarkerControl">
        				<Grid x:Name="grid" HorizontalAlignment="Center" Height="7" RenderTransformOrigin="0.5,0.5" ToolTipService.ToolTip="{Binding Content}" VerticalAlignment="Bottom" Width="7">
        					<Grid.Projection>
        						<PlaneProjection />
        					</Grid.Projection>
        					<Grid.RenderTransform>
        						<CompositeTransform />
        					</Grid.RenderTransform>
        					<VisualStateManager.VisualStateGroups>
        						<VisualStateGroup x:Name="CommonStates">
        							<VisualState x:Name="Normal" />
        							<VisualState x:Name="StateMouseOver" />
        						</VisualStateGroup>
        						<VisualStateGroup x:Name="MarkerTypes">
        							<VisualState x:Name="timeline">
        								<Storyboard>
        									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="timeline_path">
        										<DiscreteObjectKeyFrame KeyTime="0">
        											<DiscreteObjectKeyFrame.Value>
        												<Visibility>Visible</Visibility>
        											</DiscreteObjectKeyFrame.Value>
        										</DiscreteObjectKeyFrame>
        									</ObjectAnimationUsingKeyFrames>
        								</Storyboard>
        							</VisualState>
                                    <VisualState x:Name="timelinecustom">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="timelinecustom_path">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="chapter">
        								<Storyboard>
        									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="rectangle">
        										<DiscreteObjectKeyFrame KeyTime="0">
        											<DiscreteObjectKeyFrame.Value>
        												<Visibility>Visible</Visibility>
        											</DiscreteObjectKeyFrame.Value>
        										</DiscreteObjectKeyFrame>
        									</ObjectAnimationUsingKeyFrames>
        								</Storyboard>
        							</VisualState>
        						</VisualStateGroup>
        					</VisualStateManager.VisualStateGroups>
        					<Path x:Name="timeline_path" Data="M0.044930875,0.044930875 L0.044930875,13.928502 L14.310663,0.067577466 z" Fill="#FF8DE6FC" HorizontalAlignment="Left" Height="7" Margin="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#FF2A2A2A" StrokeThickness="0.5" UseLayoutRounding="False" Visibility="Collapsed" VerticalAlignment="Top" Width="7" d:LayoutOverrides="HorizontalMargin">
        						<Path.RenderTransform>
        							<CompositeTransform TranslateY="-8" />
        						</Path.RenderTransform>
        					</Path>
                            <Path x:Name="timelinecustom_path" Data="M0.044930875,0.044930875 L0.044930875,13.928502 L14.310663,0.067577466 z" Fill="Red" HorizontalAlignment="Left" Height="7" Margin="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="#FF2A2A2A" StrokeThickness="0.5" UseLayoutRounding="False" Visibility="Collapsed" VerticalAlignment="Top" Width="7" d:LayoutOverrides="HorizontalMargin">
                                <Path.RenderTransform>
                                    <CompositeTransform TranslateY="-8" />
                                </Path.RenderTransform>
                            </Path>
                            <Rectangle x:Name="rectangle" Fill="White" Height="5" Opacity="0.6" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5" Visibility="Collapsed" Width="1">
        						<Rectangle.RenderTransform>
        							<CompositeTransform TranslateY="-1" />
        						</Rectangle.RenderTransform>
        					</Rectangle>
        				</Grid>
        			</ControlTemplate>
                </Setter.Value>
        	</Setter>
        
-->
        
        	
        	
        
        <!--
        	<Setter Property="Template">
        		<Setter.Value>
        			<ControlTemplate TargetType="Core:Timeline">
        				<Grid x:Name="MainLayout">
        					<VisualStateManager.VisualStateGroups>
        						<VisualStateGroup x:Name="CommonStates">
        							<VisualStateGroup.Transitions>
        								<VisualTransition GeneratedDuration="0:0:0.25" />
        							</VisualStateGroup.Transitions>
        							<VisualState x:Name="Normal" />
        							<VisualState x:Name="MouseOver" />
        							<VisualState x:Name="Disabled">
        								<Storyboard>
        									<DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MainLayout" />
        								</Storyboard>
        							</VisualState>
        						</VisualStateGroup>
        						<VisualStateGroup x:Name="FocusStates">
        							<VisualStateGroup.Transitions>
        								<VisualTransition GeneratedDuration="0:0:0.25" />
        							</VisualStateGroup.Transitions>
        							<VisualState x:Name="Unfocused" />
        							<VisualState x:Name="Focused">
        								<Storyboard />
        							</VisualState>
        						</VisualStateGroup>
        						<VisualStateGroup x:Name="LiveStates">
        							<VisualState x:Name="Live">
        								<Storyboard>
        									<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="HorizontalAvailableBar">
        										<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1" />
        									</DoubleAnimationUsingKeyFrames>
        								</Storyboard>
        							</VisualState>
        							<VisualState x:Name="Vod">
        								<Storyboard>
        									<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="HorizontalAvailableBar">
        										<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1" />
        									</DoubleAnimationUsingKeyFrames>
        								</Storyboard>
        							</VisualState>
        						</VisualStateGroup>
        					</VisualStateManager.VisualStateGroups>
        					<Grid x:Name="HorizontalTemplate" Background="Transparent" IsHitTestVisible="True">
        						<Grid.ColumnDefinitions>
        							<ColumnDefinition Width="Auto" />
        							<ColumnDefinition Width="Auto" />
        							<ColumnDefinition Width="*" />
        						</Grid.ColumnDefinitions>
        						<RepeatButton x:Name="HorizontalTrackLargeChangeIncreaseRepeatButton" Grid.Column="2" IsHitTestVisible="False">
        							<RepeatButton.Template>
        								<ControlTemplate>
        									<Rectangle Height="8" StrokeThickness="0.5">
        										<Rectangle.Fill>
        											<LinearGradientBrush EndPoint="0.813735,1" StartPoint="0.813735,7.62934e-006">
        												<GradientStop Color="#FF374450" Offset="0" />
        												<GradientStop Color="#FF253039" Offset="0.268319" />
        												<GradientStop Color="#FF141C23" Offset="0.76569" />
        											</LinearGradientBrush>
        										</Rectangle.Fill>
        										<Rectangle.Stroke>
        											<LinearGradientBrush EndPoint="0.813346,0.970588" StartPoint="0.813346,0.0294187">
        												<GradientStop Color="#FF000000" Offset="0.447699" />
        												<GradientStop Color="#FF7F7F7F" Offset="0.800973" />
        												<GradientStop Color="#FFFFFFFF" Offset="1" />
        											</LinearGradientBrush>
        										</Rectangle.Stroke>
        									</Rectangle>
        								</ControlTemplate>
        							</RepeatButton.Template>
        						</RepeatButton>
        						<Border x:Name="HorizontalAvailableBar" BorderThickness="0" Grid.ColumnSpan="3" HorizontalAlignment="Left" Height="6" Margin="0" Opacity="0" Padding="0">
        							<Border.BorderBrush>
        								<LinearGradientBrush EndPoint="0.813346,0.970588" StartPoint="0.813346,0.0294187">
        									<GradientStop Color="#FF000000" Offset="0.447699" />
        									<GradientStop Color="#FF7F7F7F" Offset="0.800973" />
        									<GradientStop Color="#FFFFFFFF" Offset="1" />
        								</LinearGradientBrush>
        							</Border.BorderBrush>
        							<Border.Background>
        								<LinearGradientBrush EndPoint="0.339394,1.01667" StartPoint="0.339394,-0.0166667">
        									<GradientStop Color="#FFBCE6F8" Offset="0" />
        									<GradientStop Color="#FF7496A5" Offset="0.313808" />
        									<GradientStop Color="#FF2C4652" Offset="1" />
        								</LinearGradientBrush>
        							</Border.Background>
        						</Border>
        						<RepeatButton x:Name="HorizontalTrackLargeChangeDecreaseRepeatButton" Grid.Column="0" IsHitTestVisible="False" IsTabStop="False">
        							<RepeatButton.Template>
        								<ControlTemplate>
        									<Rectangle Height="8" StrokeThickness="0.5">
        										<Rectangle.Fill>
        											<LinearGradientBrush EndPoint="0.666919,1.00833" StartPoint="0.666919,0">
        												<GradientStop Color="#FFFFFFFF" Offset="0" />
        												<GradientStop Color="#FFDDF2FB" Offset="0.19376" />
        												<GradientStop Color="#FFBCE6F8" Offset="0.481172" />
        												<GradientStop Color="#FFACD0DF" Offset="0.646463" />
        												<GradientStop Color="#FF9CBAC7" Offset="0.991632" />
        											</LinearGradientBrush>
        										</Rectangle.Fill>
        										<Rectangle.Stroke>
        											<LinearGradientBrush EndPoint="0.813346,0.970588" StartPoint="0.813346,0.0294187">
        												<GradientStop Color="#FF000000" Offset="0.447699" />
        												<GradientStop Color="#FF7F7F7F" Offset="0.800973" />
        												<GradientStop Color="#FFFFFFFF" Offset="1" />
        											</LinearGradientBrush>
        										</Rectangle.Stroke>
        									</Rectangle>
        								</ControlTemplate>
        							</RepeatButton.Template>
        						</RepeatButton>
                                <Core:MarkerItemsControl Grid.ColumnSpan="3" Grid.Column="0" EndPosition="{TemplateBinding EndPosition}" IsLive="{TemplateBinding IsLive}" ItemsSource="{TemplateBinding Markers}" LivePosition="{TemplateBinding LivePosition}" RenderTransformOrigin="0.5,0.5" StartPosition="{TemplateBinding StartPosition}" ThumbWidth="{Binding Width, ElementName=HorizontalThumb}" ItemTemplate="{StaticResource DataTemplateCustom}" />
        						<Thumb x:Name="HorizontalThumb" Background="#00FFFFFF" Grid.Column="1" Height="16" Style="{StaticResource ThumbStyle}" Width="9" />
        					</Grid>
        				</Grid>
        			</ControlTemplate>
        		</Setter.Value>
        	</Setter>
        
-->

Feb 23, 2012 at 6:57 AM

Hey thanks so much for responding!

Unfortunately, I stopped work on this project in August and don't even have access to the code base. When I get back into Silverlight in the coming months I'll be sure to look at your suggestion to guide me! FYI, I ended up rolling a crappy DIY media player and made basic markers for it. I learned a lot of Silverlight in the process (though I didn't get the experience of working with the much more powerful MMP) and the project turned out pretty nicely.

Thanks again!