Search code examples
wpfbindingoneway

Disable custom WPF control when binding is oneway


I have a custom WPF control (using UserControl as base) that exposes a bindable properties (using DependencyProperty). I want to disable editing in this control when one of the properties is a oneway binding.

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);
        }
    }

           

Usage point

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

So when IsChecked is a oneway binding I want to disable editing in OnOffControl. How does one go about detecting the property binding is OneWay inside of the control and then disable editing?


Solution

  • You may check if there is a Binding and get the Binding's properties in a PropertyChangedCallback:

    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;
    }