WPF 中的只读切换按钮或复选框

问题描述 投票:0回答:1

默认情况下,WPF ToggleButton 或 CheckBox(继承 ToggleButton)没有某种 ReadOnly 属性来阻止用户更改值。

一项技术在于设置

IsHitTestVisible="False"
Focusable="False"

我认为我也可以实现将

IsChecked
属性绑定到
get
仅访问器。

绑定模型

class SomeViewModel
{
  public bool Checked => true;
}

查看

<CheckBox IsChecked="{Binding Checked, Mode=OneWay}">

但不幸的是,这不起作用,用户仍然可以更改 CheckBox 值...

c# .net wpf checkbox togglebutton
1个回答
0
投票

不幸的是,在这种情况下,当用户更改值时,绑定会不同步。

下面的解决方案包括在用户更改值时始终刷新绑定。

ToggleButtonEx 类

public class ToggleButtonEx
{

    public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.RegisterAttached(
        "IsReadOnly", typeof(bool), typeof(ToggleButtonEx), new PropertyMetadata(default(bool), OnPropertyChanged));

    private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not ToggleButton toggleButton)
            throw new InvalidOperationException($"This property may only be set on {nameof(ToggleButton)}.");

        if ((bool)e.NewValue)
        {
            toggleButton.Checked += OnCheckChanged;
            toggleButton.Unchecked += OnCheckChanged;
        }
        else
        {
            toggleButton.Checked -= OnCheckChanged;
            toggleButton.Unchecked -= OnCheckChanged;
        }
    }

    private static void OnCheckChanged(object sender, RoutedEventArgs e)
    {
        var checkedBinding = ((CheckBox)sender).GetBindingExpression(ToggleButton.IsCheckedProperty);
        checkedBinding?.UpdateTarget();
    }

    public static void SetIsReadOnly(DependencyObject element, bool value)
    {
        element.SetValue(IsReadOnlyProperty, value);
    }

    public static bool GetIsReadOnly(DependencyObject element)
    {
        return (bool)element.GetValue(IsReadOnlyProperty);
    }
}

使用方法

<CheckBox IsChecked="{Binding Checked, Mode=OneWay}" ns:ToggleButtonEx.IsReadOnly="True">
© www.soinside.com 2019 - 2024. All rights reserved.