依赖项 属性 更改时未引发 WPF 事件

WPF Event Not Raised when Dependency Property Changed

我有以下基于 "heavy option" at this link 的自定义控件:

public partial class SelectableContentControl : ContentControl
{
    public SelectableContentControl()
    {
        InitializeComponent();
        var isCheckedDesc = DependencyPropertyDescriptor.FromProperty(IsCheckedProperty, typeof(SelectableContentControl));
        isCheckedDesc.AddValueChanged(this, IsCheckedPropertyChanged);
    }

    public bool IsChecked
    {
        get { return (bool)GetValue(IsCheckedProperty); }
        set { SetValue(IsCheckedProperty, value); }
    }

    public static readonly DependencyProperty IsCheckedProperty =
        DependencyProperty.Register("IsChecked", typeof(bool),
          typeof(SelectableContentControl), new PropertyMetadata(false));

    private void IsCheckedPropertyChanged(object sender, EventArgs e)
    {
        var selectable = Content as IAmSelectable;
        if (selectable != null) selectable.IsSelected = IsChecked;
    }
}

SelectableContentControl定义的样式如下:

<Style TargetType="{x:Type controls1:SelectableContentControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls1:SelectableContentControl}">
                <CheckBox IsChecked="{TemplateBinding IsChecked}"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

...以及我的用法:

<controls:SelectableContentControl Grid.Row="2" Content="{Binding Dummy}" IsChecked="{Binding Dummy.IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

我希望 IsCheckedPropertyChanged 在 UI 上的 IsChecked 值发生变化时被调用,但这并没有发生。有人看到我遗漏了什么吗?

TemplateBindingOneWay 模式下工作,这意味着该值仅在源到目标方向上更新(您的控件是源,而 CheckBox 在模板目标)。如果您希望绑定在 TwoWay 模式下工作,您应该使用普通的 Binding 代替:

<ControlTemplate TargetType="{x:Type controls1:SelectableContentControl}">
    <CheckBox IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}}" />
</ControlTemplate>

请注意,您不需要在绑定上指定Mode=TwoWay,因为CheckBox.IsChecked 属性默认以双向模式绑定。

有关详细信息,请参阅 this question