【问题标题】:How to access a named element of a derived user control in silverlight?如何在 Silverlight 中访问派生用户控件的命名元素?
【发布时间】:2011-02-06 21:20:49
【问题描述】:

我在 silverlight 中有一个自定义的基本用户控件。

<UserControl x:Class="Problemo.MyBaseControl"
    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"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Border Name="HeaderControl" Background="Red" />
    </Grid>
</UserControl>

后面有以下代码

public partial class MyBaseControl : UserControl
    {
        public UIElement Header { get; set; }

        public MyBaseControl()
        {
            InitializeComponent();
            Loaded += MyBaseControl_Loaded;
        }

        void MyBaseControl_Loaded(object sender, RoutedEventArgs e)
        {
            HeaderControl.Child = Header;
        }
    }

我有一个派生控件。

<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="header" Text="{Binding Text}" />
    </me:MyBaseControl.Header> 
</me:MyBaseControl>

后面有以下代码。

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

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

我正在尝试在派生控件中设置标题文本块的文本值。

如果能够同时设置两种方式,即使用数据绑定或在派生控制代码中设置,那就太好了,但两者都不起作用。使用数据绑定,它不起作用。如果我在后面的代码中尝试,我会得到一个对“标题”的空引用。这是 silverlight 4(不确定这是否有所不同)

关于如何处理数据绑定和代码的任何建议?

干杯

【问题讨论】:

    标签: silverlight data-binding user-controls controls


    【解决方案1】:

    首先,我将向您展示如何调整您的 Derived 控件来处理此问题。您需要做两件事,首先您需要实现INotifyPropertyChanged,其次您需要将绑定添加到用户控件。

    MyControl Xaml:-

    <me:MyBaseControl.Header>     
        <TextBlock Name="headerItem" />     
    </me:MyBaseControl.Header>
    

    MyControl 代码:-

    public partial class MyControl : MyBaseControl, INotifyPropertyChanged
    {
        public MyControl ()
        {
            InitializeComponent();
            headerItem.SetBinding(TextBlock.TextProperty, new Binding("Text") { Source = this });
        }
    
        string _text;
        public string Text
        {
            get { return _text; }
            set { _text = value; NotifyPropertyChanged("Text"); }
        }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    
        #endregion
    }
    

    这应该让你工作。 然而,一旦您觉得需要继承基于 UserControl 的类,您就应该退后一步,询问是否应该改为模板化控件。如果我有时间,我会尝试根据模板控件添加您的代码版本。

    【讨论】:

    • 谢谢。基类是模板化的(它几乎是一个窗口,有一个标题、内容、最小化/最大化)如果我在这个示例中将基本控件更改为模板化控件,代码失败,headerItem 为空。关于让它 2 与模板化基本控件一起工作的任何建议? 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; }}
    • @Mrt:我并不是建议您应该使用模板化控件,只是因为它可能值得考虑。既然你已经透露了更多关于你在做什么的信息,你有什么理由不使用内置的ChildWindow 类吗?顺便说一句,代码不会在注释中格式化,如果您想使用模板化控制方法发布另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 2011-02-07
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多