2017-02-20 3 views
0

DockPanel、ToggleButton、ComboBoxなどから派生したカスタムコントロールがいくつかあります。これらの派生クラスのそれぞれに依存プロパティとして使用するクラスPropsがあります。これらのクラスはすべて同じ依存プロパティ(Propsに含まれています)と独自のプロパティ(たとえばDockパネルのみ)を持つ必要があります。 ユースケースの例は、プロパティ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は、ビューのロード時にのみ呼び出され、ボタンを使用して表示を切り替えようとした場合は呼び出されません。私がRightVisibleExistsInConfigのPropertyMetadataでコールバックを指定すると、ボタンをトグルした後に呼び出されますが、コンバーターは呼び出されません。

Propsが変更されたことをDockPanelに知らせなければなりませんか?それについてどうすればいいですか?私はINotifyPropertyChangedを2つのクラスにわたって実装する方法を考え出すことができませんでした。

+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> 
関連する問題