单向绑定时禁用自定义 WPF 控件

Disable custom WPF control when binding is oneway

我有一个公开可绑定属性(使用 DependencyProperty)的自定义 WPF 控件(使用 UserControl 作为基础)。当其中一个属性是单向绑定时,我想在此控件中禁用编辑。

public partial class OnOffControl : UserControl
{
    ...

    public static readonly DependencyProperty IsCheckedProperty =
        DependencyProperty.Register(
            "IsChecked",
            typeof(bool?),
            typeof(OnOffControl),
    ...
    public bool? IsChecked
    {
        get
        {
            return (bool?)GetValue(IsCheckedProperty);
        }

        set
        {
            SetValue(IsCheckedProperty, value);
        }
    }

           

使用点

                        <DataGridTemplateColumn Width="40" Header="State">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <UIUtil:OnOffControl 
                                        IndicatorType="SwitchIndicator"
                                        IsChecked="{Binding Value, Mode=OneWay}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>

因此,当 IsChecked 是单向绑定时,我想禁用 OnOffControl 中的编辑。如何检测控件内部的 属性 绑定是单向的,然后禁用编辑?

您可以检查是否存在 Binding 并在 PropertyChangedCallback 中获取 Binding 的属性:

public static readonly DependencyProperty IsCheckedProperty =
    DependencyProperty.Register(
        nameof(IsChecked),
        typeof(bool?),
        typeof(OnOffControl),
        new PropertyMetadata(IsCheckedPropertyChanged));

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

private static void IsCheckedPropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    var control = (OnOffControl)o;
    var binding = control.GetBindingExpression(IsCheckedProperty)?.ParentBinding;
    var enabled = false;

    if (binding != null)
    {
        enabled = binding.Mode == BindingMode.TwoWay
               || binding.Mode == BindingMode.OneWayToSource;
    }

    control.IsEnabled = enabled;
}