绑定到自定义控件的嵌套依赖项属性

绑定到自定义控件的嵌套依赖项属性

问题描述:

我有几个从DockPanel,ToggleButton,ComboBox等派生的自定义控件。我有一个类Props,我想在每个派生类中用作依赖项属性。所有这些类都需要具有相同的依赖项属性(包含在Props中),并且可能具有其自己的几个独特属性(例如,仅在Dock Panel中)。 示例用例是属性ExistsInConfig和RightVisible。我希望控件仅在两者都设置为true时才可见。这个逻辑应该在我所有的自定义派生控件中都可用。绑定到自定义控件的嵌套依赖项属性

DockPanel.cs:

public class DockPanel : System.Windows.Controls.DockPanel 
{ 
    public DockPanel() 
    { 
     Props = new Props(); 
    } 

    public Props Props 
    { 
     get 
     { 
      return (Props)GetValue(Properties); 
     } 
     set 
     { 
      SetValue(Properties, value); 
     } 
    } 

    public static readonly DependencyProperty Properties = 
    DependencyProperty.Register("Props", typeof(Props), typeof(DockPanel), new PropertyMetadata(null)); 
} 

Props.cs:

public class Props: DependencyObject 
{ 
    public Props(){} 

    public bool RightVisible { get; set;} 

    public bool ExistsInConfig { get; set; } 

    public static readonly DependencyProperty RightVisibleProperty = 
    DependencyProperty.Register("RightVisible", typeof(bool), typeof(Props), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

    public static readonly DependencyProperty ExistsInConfigProperty = 
    DependencyProperty.Register("ExistsInConfig", typeof(bool), typeof(Props), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

    public static bool GetExistsInConfig(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(ExistsInConfigProperty); 
    } 

    public static void SetExistsInConfig(DependencyObject obj, bool value) 
    { 
     obj.SetValue(ExistsInConfigProperty, value); 
    } 

    public static bool GetRightVisible(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(RightVisibleProperty); 
    } 

    public static void SetRightVisible(DependencyObject obj, bool value) 
    { 
     obj.SetValue(RightVisibleProperty, value); 
    } 
} 

样式DockPanel中:

<Style x:Key="CustomDockPanelStyle" TargetType="custom:DockPanel"> 
    <Setter Property="Visibility"> 
     <Setter.Value> 
      <MultiBinding Converter="{StaticResource MultipleBooleanToVisibilityConverter}"> 
       <Binding RelativeSource="{RelativeSource Self}" Path="Props.ExistsInConfig" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged"/> 
       <Binding RelativeSource="{RelativeSource Self}" Path="Props.RightVisible" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged" /> 
      </MultiBinding> 
     </Setter.Value> 
    </Setter> 
</Style> 

使用在XAML控制:

<Window.Resources> 
    <Style TargetType="{x:Type custom:DockPanel}" BasedOn={StaticResource CustomDockPanelStyle}" 
</Window.Resources> 

<custom:DockPanel 
custom:Props.ExistsInConfig="{Binding ElementName=ToggleCombinedVisibility, Path=IsChecked, Mode=OneWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
custom:Props.RightVisible="{Binding ElementName=ToggleCombinedVisibility, Path=IsChecked, Mode=OneWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"> 

<ToggleButton x:Name="ToggleCombinedVisibility" IsChecked="True" /> 

问题是,绑定不起作用。 MultipleBooleanToVisibilityConverter只会在加载视图时调用,而不是在我尝试使用按钮切换可见性时调用。如果我在PropertyMetadata中指定回调RightVisibleExistsInConfig,它们会在切换按钮后被调用,但转换器不会。

我是否必须让DockPanel知道Props已更改?我该如何解决这个问题?我无法想象在两个班级中实施INotifyPropertyChanged的方法。

+0

请问downvoters照顾解释吗? – gingergenius

Style中的绑定路径错误。

附加属性应该由括号和自定义附加属性包围,前面应该有一个名称空间别名。

这应该工作:

<Style x:Key="CustomDockPanelStyle" TargetType="custom:DockPanel"> 
    <Setter Property="Visibility"> 
     <Setter.Value> 
      <MultiBinding Converter="{StaticResource MultipleBooleanToVisibilityConverter}"> 
       <Binding RelativeSource="{RelativeSource Self}" Path="(custom:Props.ExistsInConfig)" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged"/> 
       <Binding RelativeSource="{RelativeSource Self}" Path="(custom:Props.RightVisible)" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" UpdateSourceTrigger="PropertyChanged" /> 
      </MultiBinding> 
     </Setter.Value> 
    </Setter> 
</Style>