How do I change a Silverlight template at runtime?

I have a custom control that contains a templated path. I want to be able to get a reference to the grid in the template at runtime so that I can modify it based on usage.

I thought I could use GetTemplateChild to get the grid reference in the template from the control's OnApplyTemplate method, but that method doesn't work.

public override void OnApplyTemplate()
{
  base.OnApplyTemplate();

  _tooltipDetails = (Grid)GetTemplateChild("TooltipDetailsGrid");
}

      

How else can I do this?

Here is a custom XAML control.

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Class="MiX.AssetManagement.UI.Timeline.Silverlight.TimelineBarRibbonItem"
    FontSize="9.333" Foreground="White" mc:Ignorable="d">
    <UserControl.Resources>
        <ControlTemplate x:Key="ToolTipControlTemplateTimelineView" TargetType="ToolTip">
            <StackPanel Orientation="Horizontal" Margin="16,0,0,0">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="OpenStates">
                        <VisualState x:Name="Closed"/>
                        <VisualState x:Name="Open"/>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Border CornerRadius="4">
                    <Border.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#7F000000" Offset="0"/>
                            <GradientStop Color="#B2000000" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                    <Grid Margin="4">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Border x:Name="Info" Height="16" Width="16" BorderThickness="2" CornerRadius="8" HorizontalAlignment="Left" VerticalAlignment="Top">
                            <Border.BorderBrush>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="White" Offset="0"/>
                                    <GradientStop Color="#7FFFFFFF" Offset="1"/>
                                </LinearGradientBrush>
                            </Border.BorderBrush>
                            <Path Fill="White" Stretch="Fill" Margin="5.229,2.089,5.035,2.82" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" Data="M0.77471197,5.0623446 L2.4198356,5.0623446 L2.4198356,10.18 L0.77471197,10.18 z M0.72914064,3.0891075 L2.4654069,3.0891075 L2.4654069,4.3332038 L0.72914064,4.3332038 z">
                                <Path.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </Path.RenderTransform>
                            </Path>
                        </Border>
                        <ContentPresenter d:LayoutOverrides="Width, Height" Margin="20,0,0,0"/>
                        <Grid Grid.Column="1" x:Name="TooltipDetailsGrid">
                            <TextBlock Text="Tooltip in a Grid"/>
                        </Grid>
                    </Grid>
                </Border>
            </StackPanel>
        </ControlTemplate>
    </UserControl.Resources>

    <Path x:Name="RibbonItem" Cursor="Hand">
        <Path.Fill>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF66CC33"/>
                <GradientStop Color="#FF339900" Offset="1"/>
            </LinearGradientBrush>
        </Path.Fill>
        <ToolTipService.ToolTip>
            <ToolTip x:Name="RibbonItemTooltip" Content="" Foreground="#FFFFFFFF" FontSize="9.333" Placement="Mouse" Template="{StaticResource ToolTipControlTemplateTimelineView}"/>
        </ToolTipService.ToolTip>
        <Path.Data>
            <GeometryGroup x:Name="RibbonItemGeometryGroup">
                <RectangleGeometry x:Name="RibbonItemBackground" />
            </GeometryGroup>
        </Path.Data>
    </Path>
</UserControl>

      

+2


source to share


2 answers


I solved it in a slightly different way. Instead of changing the template at runtime, I created an instance of the template for each use case. Then I can apply the correct template when I instantiate and the items in the template binding to the control class to populate the tooltip with the appropriate values.



This is probably the best approach as the tooltip structure is now clearly visible in XAML rather than hidden in code.

0


source


You need to process the code in the ToolApptTextType method. Here is my untested hit on what you need to do: -

Inherit from ToolTip and override OnApplyTemplate method in this new class: -

 public MyToolTip : ToolTip
 {
     public override void OnApplyTemplate()
     {
         //Perhaps to stuff
         base.OnApplyTemplate();
         //Perhaps to other stuff
     }
 }

      



In your resources, now set TargetType

to local:MyToolTip

and make sure the assembly namespace is aliased local

in the user control.

Now in your Xaml: -

    <ToolTipService.ToolTip>
            <local:MyToolTip x:Name="RibbonItemTooltip" Content="" Foreground="#FFFFFFFF" FontSize="9.333" Placement="Mouse" Template="{StaticResource ToolTipControlTemplateTimelineView}"/>
    </ToolTipService.ToolTip>

      

+1


source







All Articles