逻辑组合依赖项属性

时间:2011-01-19 21:42:51

标签: wpf c#-4.0 dependency-properties

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

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

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

  1. 实现这一目标的最佳方法是什么?
  2. 我还在考虑让PropC成为一个只读的DependencyProperty,但是已经阅读了关于绑定到readonly dp的问题(WPF ReadOnly Dependency Properties using MVVM

2 个答案:

答案 0 :(得分:3)

您可以使用PropA和PropB的Dependency Property更改回调来设置PropC的值(不要使用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;
}

这样,您每次PropCPropA更改

时始终会更新PropB的值

此外,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));
    }
}

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

答案 1 :(得分:0)

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

修改

以下是一个例子:

<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;
    }
}