将UserControl属性绑定到INotifyPropertyChanged视图模型

时间:2012-09-19 13:19:00

标签: .net wpf

这里给出的示例是我试图实现的实际UserControl的简化,但它说明了结构并遇到了同样的问题。用户控件具有DependencyProperty Words,用于设置用户控件XAML中定义的textblock文本。

    public partial class MyControl : UserControl
    {
        public static readonly DependencyProperty WordsProperty = DependencyProperty.Register("Words", typeof(string), typeof(MyControl));
        public MyControl()
        {
            InitializeComponent();
        }
        public string Words
        {
            get { return (string)GetValue(WordsProperty); }
            set
            {
                m_TextBlock.Text = value;
                SetValue(WordsProperty, value);
            }

将一个INotifyPropertyChanged ViewModelBase类派生的ViewModel分配给mainWindow DataContext。 ModelText属性集调用OnPropertyChanged。

class MainWindow : ViewModelBase
{
    private string m_ModelString;
    public string ModelText
    {
        get { return m_ModelString; }
        set
        {
            m_ModelString = value;
            base.OnPropertyChanged("ModelText");
        }
    }
}

在MainWindow中,XAML绑定到UserControl和TextBlock

 <Window x:Class="Binding.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="218" Width="266" xmlns:my="clr-namespace:Binding.View">
    <Grid>
        <my:MyControl Words="{Binding ModelText}" HorizontalAlignment="Left" Margin="39,29,0,0" x:Name="myControl1" VerticalAlignment="Top" Height="69" Width="179" Background="#FF96FF96" />
        <TextBlock Height="21" HorizontalAlignment="Left" Margin="59,116,0,0" Name="textBlock1" Text="{Binding ModelText}" VerticalAlignment="Top" Width="104" Background="Yellow" />
    </Grid>
</Window>

绑定适用于文本块,但不适用于用户控件。为什么UserControl DependencyProperty不能以与Control Properties相同的方式绑定?

2 个答案:

答案 0 :(得分:0)

罪魁祸首是:

m_TextBlock.Text = value;

WPF不直接使用DP支持的属性。

如果您想在修改m_TextBlock.Text时更新WordsProperty,请将该文本块绑定到Words,或使用PropertyChangedCallback中的UIPropertyMetadata:< / p>

 public static readonly DependencyProperty WordsProperty = 
         DependencyProperty.Register("Words", 
                                    typeof(string), 
                                    typeof(MyControl),
                                    new UIPRopertyMetadata(
                 new PropertyChangedCallback(
                     (dpo, dpce) => 
                     {
                         //Probably going to need to first cast dpo to MyControl
                         //And then assign its m_TextBlock property's text.
                         m_TextBlock.Text = dpce.NewValue as string;
                     })));

考虑dpo发件人,dpce事件参数。

答案 1 :(得分:0)

我认为您应该通过绑定而不是m_TextBlock.Text = value;将文本分配给UserControl的文本框。

也许您可以在UserControl Xaml中使用这样的绑定:

    Text="{Binding Words
, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"