如何访问从模板控件继承的控件中的命名元素 [英] How to access a named element in a control that inherits from a templated control

查看:57
本文介绍了如何访问从模板控件继承的控件中的命名元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,这类似于如何在Silverlight中访问派生用户控件的命名元素?,区别是从模板控件而不是用户控件继承。

Hello this is similar to How to access a named element of a derived user control in silverlight? with the difference is inheriting from a templated control, not a user control.

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

I have a templated control called 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控件

I have another control called myControl which inherits from 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为空。如何在后面的代码中访问xxx控件?

The issue is xxx is null. How do I access the xxx control in the code behind ?

推荐答案

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

When you access the HeaderControl, that is being pulled from the ControlTemplate. The elements in the ControlTemplate are created and added as visual descendants of the control. Then the OnApplyTemplate method is called and you can access them via their name.

在第二种情况下,您专门为Header属性分配了一个元素。在这种情况下,由于显式设置了标题,因此无法获得命名元素。

In the second case, you are specifically assigning a single element to the Header property. There is no way to get a "named" element in this case, as the header is being explicitly set.

如果知道,可以直接转换Header属性它将是一个TextBlock,例如:

You could cast the Header property directly, if you know that it's going to be a TextBlock, like so:

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

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

Otherwise, you could bind the TextBlock to your Text property in your XAML, like so:

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

后一种绑定方法是更好的选择,因为您不受特定控件的束缚(即TextBlock)。

The latter method of binding is the better way to go, since you are not tied to a given control (i.e. TextBlock).

这篇关于如何访问从模板控件继承的控件中的命名元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆