从 Thumb 控件的子类更新 ControlTemplate 的控件文本

Update ControlTemplate's control text from a subclass of Thumb control

我有一个 class 继承了 Thumb(为简洁起见截断):

public class MyControl : Thumb
{
    public MyControl()
      : base()
    {
        this.MinWidth = 80;
        this.MinHeight = 60;

        /* ... */
    }
}

我有一个 ControlTemplate,如下所示:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<ControlTemplate x:Key="MyControlTemplate">
    <Border BorderBrush="Black" BorderThickness="1" Name="border">
        <StackPanel>
            <StackPanel.Background>
                <SolidColorBrush Color="White" Opacity="1"/>
            </StackPanel.Background>
            <TextBlock Name="controlType" Padding="5,0,5,3" HorizontalAlignment="Stretch" TextAlignment="Center">
                <TextBlock.Background>
                    <SolidColorBrush Color="#FFC0C0C0" Opacity="1"/>
                </TextBlock.Background>
            </TextBlock>
        </StackPanel>
    </Border>
</ControlTemplate>

我在另一个 class 中实例化了 MyControl 的实例,并尝试在模板中设置 controlType TextBlock 控件的 Text 属性。

public System.Windows.UIElement Create()
{
    MyControl control = new MyControl();
    var template = Application.Current.Resources["MyControlTemplate"] as ControlTemplate;

    var contents = template.LoadContent();
    var panel = (StackPanel)VisualTreeHelper.GetChild(contents, 0);
    foreach (var textBlock in panel.Children.OfType<TextBlock>())
    {
        switch (textBlock.Name)
        {
            case "controlType":
                textBlock.Text = "MyText";
                textBlock.InvalidateVisual();
                break;
        }
    }

    control.Template = template;
    control.UpdateLayout();

    return control;
}

但是,文本 "MyText" 没有显示在 TextBlock 中。我错过了什么?

LoadContent() 方法将模板的内容作为单独的实例加载。这不是你想要的。您要设置应用于 MyControl 实例的 TextBlockText 属性:

public System.Windows.UIElement Create()
{
    MyControl control = new MyControl();
    var template = Application.Current.Resources["MyControlTemplate"] as ControlTemplate;
    control.Template = template;
    control.ApplyTemplate();

    var border = (Border)VisualTreeHelper.GetChild(control, 0);
    var panel = (StackPanel)VisualTreeHelper.GetChild(border, 0);
    foreach (var textBlock in panel.Children.OfType<TextBlock>())
    {
        switch (textBlock.Name)
        {
            case "controlType":
                textBlock.Text = "MyText";
                textBlock.InvalidateVisual();
                break;
        }
    }
    return control;
}