【问题标题】:WPF - property change notification from UserControlWPF - 来自 UserControl 的属性更改通知
【发布时间】:2010-08-31 23:08:10
【问题描述】:

我有两个用户控件(uc1 和 uc2)加载到第三个用户控件(shell)中。 Shell 有两个属性 uc1 和 uc2,类型为 UserControl1 和 UserControl2,并且每个属性都有一个 DependencyProperty 注册到它们自己的名为 IsDirty 的类:

public static readonly DependencyProperty IsDirtyProperty = DependencyProperty.Register("IsDirty", typeof (bool), typeof (UserControl1));
public bool IsDirty
{
    get { return (bool) GetValue(IsDirtyProperty); }
    set { SetValue(IsDirtyProperty, value); }
}

(UserControl2 的代码相同)

Shell 将 TextBlocks 绑定到 IsDirty 属性:

<TextBlock Text="{Binding ElementName=shell, Path=Uc1.IsDirty}"/>
<TextBlock Text="{Binding ElementName=shell, Path=Uc2.IsDirty}"/>

当我在 uc1 和 uc2 中更改 IsDirty 的值时,Shell 永远不会收到通知。我错过了什么? UserControl 是 DependencyObject 的后代...

如果我有通过 INotifyPropertyChanged 通知更改的常规属性,则会发生相同的行为。

如果我从 uc1 和 uc2 引发路由事件,冒泡到 Shell,那么我可以捕获 Dirty 值并且一切正常,但我不应该这样做,不是吗?

谢谢

编辑:答案是在 Uc1 和 Uc2 属性上引发属性更改事件或将它们设为 DP。

【问题讨论】:

  • 您的绑定语句假定 Shell 在其中具有两个属性:“Uc1”和“Uc2”。它是否正确?还是“Uc1”和“Uc2”只是在 Shell 的 XAML 中添加的 UserControl 的实例?
  • 是的,这是正确的。 Shell 有两个属性:分别属于 UserControl1 和 UserControl2 类型的 uc1 和 uc2。我将使用此信息更新问题。
  • 好的。还有一个问题,为什么上面的DependencyProperty的定义叫“SecondDirtyProperty”?这是正确的还是应该是“IsDirtyProperty”?
  • 对不起,它是 IsDirtyProperty。我刚刚重命名了要在此处发布的属性:)

标签: wpf dependency-properties inotifypropertychanged


【解决方案1】:

我尝试使用简单的设置重现您的问题,并且对我来说效果很好。我不确定此设置是否足够正确以复制您的情况。无论如何,我发布它以防万一。这可能会有所帮助:

XAML:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        x:Name="shell"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Button Click="Button_Click">Click</Button>
        <TextBlock Text="{Binding ElementName=shell, Path=Uc1.IsDirty}"/>
    </StackPanel>
</Window>

代码隐藏:

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MyUserControl uc1 = new MyUserControl();
        public MyUserControl Uc1
        {
            get { return this.uc1; }
        }

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.uc1.IsDirty = !this.uc1.IsDirty;
        }


    }

    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
        }

        public bool IsDirty
        {
            get { return (bool)GetValue(IsDirtyProperty); }
            set { SetValue(IsDirtyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsDirty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsDirtyProperty =
            DependencyProperty.Register("IsDirty", typeof(bool), typeof(UserControl), new UIPropertyMetadata(false));

    }
}

【讨论】:

    【解决方案2】:

    Karmicpuppet 的回答效果很好。但是它并没有解决我的问题,因为 Shell 也是 UserControl 类型。为了让它工作,我需要提高 Uc1 和 Uc2 上的属性。当我将它们声明为 DependencyProperties 时,一切都按预期工作。呵呵!

    【讨论】:

      猜你喜欢
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多