Reputation: 21989
What is the easiest alternative of making checkBox.AutoCheck
= false
in WPF? Specifically prevent CheckBox from changing IsChecked on click.
CheckBox
should still react on clicks (Command
and/or InputBindings
), but shouldn't try to change its visual state on left click or Space key.
I can prevent bound property change by using Mode=OneWay
, but this seems have no effect on visual state, CheckBox
then become checked while my property is false
, which makes me sad...
Here is an example of checkbox:
<!-- make this checkbox behave as if AutoCheck = false -->
<CheckBox IsChecked="{Binding IsChecked, Mode=OneWay}"
Command="{Binding CommandLeftButtonOrSpace}">
<CheckBox.InputBindings>
<MouseBinding MouseAction="RightClick"
Command="{Binding CommandRightButton}" />
</CheckBox.InputBindings>
</CheckBox>
Upvotes: 4
Views: 1657
Reputation: 13030
You can prevent it from toggling in the first place by subclassing the control (from another answer):
public class OneWayCheckBox : CheckBox
{
private class CancelTwoWayMetadata : FrameworkPropertyMetadata
{
protected override void Merge(PropertyMetadata baseMetadata, DependencyProperty dp)
{
base.Merge(baseMetadata, dp);
BindsTwoWayByDefault = false;
}
}
static OneWayCheckBox()
{
// Remove BindsTwoWayByDefault
IsCheckedProperty.OverrideMetadata(typeof(OneWayCheckBox), new CancelTwoWayMetadata());
}
protected override void OnToggle()
{
// Do nothing.
}
}
This also switches the binding type of IsChecked
so that you don't need to remember to put Mode=OneWay
on it.
Upvotes: 3
Reputation: 21989
A simple attached behavior will do
public class CheckBoxBehavior
{
public static bool GetDisableAutoCheck(DependencyObject obj) => (bool)obj.GetValue(DisableAutoCheckProperty);
public static void SetDisableAutoCheck(DependencyObject obj, bool value) => obj.SetValue(DisableAutoCheckProperty, value);
public static readonly DependencyProperty DisableAutoCheckProperty =
DependencyProperty.RegisterAttached("DisableAutoCheck", typeof(bool),
typeof(CheckBoxBehavior), new PropertyMetadata(false, (d, e) =>
{
var checkBox = d as CheckBox;
if (checkBox == null)
throw new ArgumentException("Only used with CheckBox");
if ((bool)e.NewValue)
checkBox.Click += DisableAutoCheck_Click;
else
checkBox.Click -= DisableAutoCheck_Click;
}));
private static void DisableAutoCheck_Click(object sender, RoutedEventArgs e) =>
((CheckBox)sender).IsChecked = !((CheckBox)sender).IsChecked;
}
Setting like this
<ComboBox local:CheckBoxBehavior.DisableAutoCheck="True" ... />
Upvotes: 3