2017-02-20 8 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 вызывает вызов только при загрузке представления, а не когда я пытаюсь переключить видимость с помощью кнопки. Если я укажу обратные вызовы в PropertyMetadata RightVisible и ExistsInConfig, они будут вызваны после переключения кнопки, но конвертер не будет.

Должен ли я сообщить 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> 
Смежные вопросы