如何访问从模板化控件继承的控件中的命名元素

时间:2010-04-13 06:26:51

标签: silverlight templates controls

您好,这与How to access a named element of a derived user control in silverlight?类似,不同之处在于继承了模板化控件,而不是用户控件。

我有一个名为MyBaseControl的模板化控件

的Xaml: -

<Style TargetType="Problemo:MyBaseControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Problemo:MyBaseControl">
                    <Grid x:Name="LayoutRoot" Background="White">
                        <Border Name="HeaderControl" Background="Red" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

代码: -

 public class MyBaseControl : Control
    {
        public UIElement Header { get; set; }

        public MyBaseControl()
        {   
            DefaultStyleKey = typeof(MyBaseControl);
        }

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

            var headerControl = GetTemplateChild("HeaderControl") as Border;

            if (headerControl != null)
                headerControl.Child = Header;

        }
    }

我有另一个名为myControl的控件,它继承自MyBaseControl Control

的Xaml: -

<me:MyBaseControl x:Class="Problemo.MyControl"
    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"
    mc:Ignorable="d"
    xmlns:me="clr-namespace:Problemo" 
    d:DesignHeight="300" d:DesignWidth="400">
    <me:MyBaseControl.Header>
        <TextBlock Name="xxx" />
    </me:MyBaseControl.Header> 
</me:MyBaseControl>

代码: -

public partial class MyControl : MyBaseControl
{
    public string Text { get; set; }

    public MyControl(string text)
    {
        InitializeComponent();
        Text = text;
        Loaded += MyControl_Loaded;
    }

    void MyControl_Loaded(object sender, RoutedEventArgs e)
    {
        base.ApplyTemplate();
        xxx.Text = Text;
    }
}

问题是xxx为null。如何在后面的代码中访问xxx控件?

1 个答案:

答案 0 :(得分:0)

当您访问HeaderControl时,将从ControlTemplate中提取。 ControlTemplate中的元素是作为控件的可视后代创建和添加的。然后调用OnApplyTemplate方法,您可以通过其名称访问它们。

在第二种情况下,您专门为Header属性分配单个元素。在这种情况下,无法获得“命名”元素,因为标头是明确设置的。

你可以直接转换Header属性,如果你知道它将是一个TextBlock,就像这样:

TextBlock tb = this.Header as TextBlock;
if (tb != null)
    tb.Text = Text;

否则,您可以将TextBlock绑定到XAML中的Text属性,如下所示:

<me:MyBaseControl.Header>
<TextBlock Name="xxx" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type me:MyControl}}, Path=Text}" />
</me:MyBaseControl.Header>

后一种绑定方法是更好的方法,因为你没有绑定给定的控件(即TextBlock)。