【问题标题】:Binding to nested dependency properties of custom control绑定到自定义控件的嵌套依赖属性
【发布时间】:2017-02-20 12:52:29
【问题描述】:

我有几个从 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));
}

道具.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 中指定回调,它们会在切换按钮后被调用,但转换器不会。

我是否必须让 DockPanel 知道 Props 已更改?我该怎么做?我想不出在两个类中实现INotifyPropertyChanged 的方法。

【问题讨论】:

  • 反对者愿意解释一下吗?

标签: c# wpf binding dependency-properties


【解决方案1】:

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>

【讨论】:

    猜你喜欢
    • 2012-08-29
    • 2019-05-26
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2011-05-08
    • 2021-08-17
    相关资源
    最近更新 更多