【问题标题】:Logically combine dependency properties逻辑组合依赖属性
【发布时间】:2011-01-19 21:42:51
【问题描述】:

我正在使用 C# 4.0 并创建了一个 DependencyObject MyView。

在 MyView 中,我有两个 DependencyProperties,PropA 和 PropB,它们都是布尔值。

我想要第三个 DependencyProperty,PropC,也是一个 bool,简单地说,应该总是给我 (PropA || PropB)。

  1. 实现此目的的最佳方法是什么?
  2. 我也曾考虑将 PropC 设为只读 DependencyProperty,但已阅读有关绑定到只读 dp 的问题 (WPF ReadOnly Dependency Properties using MVVM)

【问题讨论】:

    标签: wpf c#-4.0 dependency-properties


    【解决方案1】:

    您可以使用 PropA 和 PropB 的 Dependency Property changed 回调来设置 PropC 的值(不要为 Dependency Properties 使用 CLR 属性包装器,因为它们永远不会被保证被调用)。

    如果你有这三个 DP

    public static readonly DependencyProperty PropAProperty =
        DependencyProperty.Register("PropA",
        typeof(bool),
        typeof(MyView),
        new PropertyMetadata(false, PropAPropertyChanged));
    
    public static readonly DependencyProperty PropBProperty =
        DependencyProperty.Register("PropB",
        typeof(bool),
        typeof(MyView),
        new PropertyMetadata(false, PropBPropertyChanged));
    
    public static readonly DependencyProperty PropCProperty =
        DependencyProperty.Register("PropC",
        typeof(bool),
        typeof(MyView),
        new PropertyMetadata(false));
    
    public bool PropA
    {
        get { return (bool)this.GetValue(PropAProperty); }
        set { this.SetValue(PropAProperty, value); }
    }
    public bool PropB
    {
        get { return (bool)this.GetValue(PropBProperty); }
        set { this.SetValue(PropBProperty, value); }
    }
    public bool PropC
    {
        get { return (bool)this.GetValue(PropCProperty); }
        set { this.SetValue(PropCProperty, value); }
    }
    

    你可以像这样使用属性改变回调

    private static void PropAPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        MyView myView = source as MyView;
        myView.OnPropChanged();
    }
    private static void PropBPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        MyView myView = source as MyView;
        myView.OnPropChanged();
    }
    public void OnPropChanged()
    {
        PropC = PropA || PropB;
    }
    

    这样,每次PropAPropB 更改时,您总是会更新PropC 的值

    另外,PropC 不需要是 DP,如果您实现 INotifyPropertyChanged,它可以是普通的 CLR 属性。然后实现可以改为这样

    public void OnPropChanged()
    {
        OnPropertyChanged("PropC");
    }   
    public bool PropC
    {
        get
        {
            return PropA || PropB;
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    您还可以使用MultiBindingPropC 绑定到PropAPropB。如果你也想要一个这样的例子,请告诉我

    【讨论】:

      【解决方案2】:

      链接的网页用于不寻常的情况,即“推送”绑定。也就是说,尝试对只读属性进行单向源绑定,而不是尝试绑定到它的另一个属性。相比之下,如果您希望您的属性在另一个属性上使用单向绑定表达式可以绑定到其他属性,那么您可以使用只读依赖属性而不会出现任何问题。

      编辑:

      这是一个例子:

      <Grid>
          <Grid.Resources>
              <local:MyObject x:Key="myObject" PropertyA="True" PropertyB="False"/>
          </Grid.Resources>
          <StackPanel DataContext="{StaticResource myObject}">
              <CheckBox IsChecked="{Binding PropertyA}"  Content="PropertyA"/>
              <CheckBox IsChecked="{Binding PropertyB}"  Content="PropertyB"/>
              <CheckBox IsChecked="{Binding PropertyC, Mode=OneWay}" IsEnabled="False"  Content="PropertyC"/>
          </StackPanel>
      </Grid>
      

      以及依赖属性,其中一个是只读的:

      public class MyObject : DependencyObject
      {
          public bool PropertyA
          {
              get { return (bool)GetValue(PropertyAProperty); }
              set { SetValue(PropertyAProperty, value); }
          }
      
          public static readonly DependencyProperty PropertyAProperty =
              DependencyProperty.Register("PropertyA", typeof(bool), typeof(MyObject), new UIPropertyMetadata(false, OnPropertyAOrBChanged));
      
          public bool PropertyB
          {
              get { return (bool)GetValue(PropertyBProperty); }
              set { SetValue(PropertyBProperty, value); }
          }
      
          public static readonly DependencyProperty PropertyBProperty =
              DependencyProperty.Register("PropertyB", typeof(bool), typeof(MyObject), new UIPropertyMetadata(false, OnPropertyAOrBChanged));
      
          public bool PropertyC
          {
              get { return (bool)GetValue(PropertyCProperty); }
              set { SetValue(PropertyCPropertyKey, value); }
          }
      
          private static readonly DependencyPropertyKey PropertyCPropertyKey =
              DependencyProperty.RegisterReadOnly("PropertyC", typeof(bool), typeof(MyObject), new UIPropertyMetadata());
          public static readonly DependencyProperty PropertyCProperty = PropertyCPropertyKey.DependencyProperty;
      
          private static void OnPropertyAOrBChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              var myObject = d as MyObject;
              myObject.PropertyC = myObject.PropertyA || myObject.PropertyB;
          }
      }
      

      【讨论】:

      • 好的,谢谢。我知道那篇文章不是我要做的,但我很好奇是否有一些类似于在这种情况下使用只读依赖属性的问题。你对如何让 PropC 工作有任何想法吗?这确实是我的主要问题(我现在已经对其进行了编辑以反映这一点)。再次感谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多