Логически объединить свойства зависимостей - PullRequest
6 голосов
/ 20 января 2011

Я использую C # 4.0 и создал DependencyObject MyView.

В MyView у меня есть два свойства DependencyProperties, PropA и PropB, оба являются логическими значениями.

Мне нужен третий DependencyProperty, PropC, также bool, и проще говоря, должен всегда давать мне (PropA || PropB).

  1. Каков наилучший способ сделать это?
  2. Я также думал о том, чтобы сделать PropC доступным только для чтения DependencyProperty, но читал о проблемах с привязкой к readonly dp's ( Свойства зависимости WPF для чтения только при использовании MVVM )

Ответы [ 2 ]

3 голосов
/ 20 января 2011

Вы можете использовать измененный обратный вызов свойства зависимости для PropA и PropB, чтобы установить значение для 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;
}

Таким образом, вы всегда будете обновлять значение PropC каждый раз PropA или PropB изменения

Кроме того, PropC не обязательно должен быть DP, это может быть обычное свойство CLR, если вы реализуете INotifyPropertyChanged. Тогда реализация может выглядеть следующим образом

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

Вы также можете связать PropC с PropA и PropB с помощью MultiBinding. Дайте мне знать, если вам нужен пример этого

0 голосов
/ 20 января 2011

Связанная веб-страница предназначена для необычной ситуации, «принудительной» привязки. То есть была предпринята попытка привязки к источнику для однонаправленного свойства, а не для другого свойства, которое пытается с ним связаться. Напротив, если вы хотите, чтобы ваше свойство связывалось с другими свойствами с помощью выражения одностороннего связывания с другим свойством , то вы можете использовать свойство зависимости только для чтения без каких-либо проблем.

Edit:

Вот пример:

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