2017-02-20 174 views
0

我有幾個從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

回答

0

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>