I have a ToggleButton
with its IsChecked
property bound to a property using a OneWay binding.
<ToggleButton
Command="{Binding Path=SomeCommand}"
IsChecked="{Binding Path=SomeProperty, Mode=OneWay}" />
The SomeCommand
toggles the boolean SomeProperty
value, and a PropertyChanged
event is raised for SomeProperty
.
If I change SomeProperty
in my viewmodel the ToggleButton
depresses correctly. However if I click the ToggleButton
the binding seems to get lost and the button no longer gets checked according to the value of SomeProperty
. Any ideas on how to fix this problem?
There is a simple and elegant way to solve the original poster's problem - replacing IsChecked property of the ToggleButton with an attachable property that will set IsChecked of the button in its change handler:
namespace TBFix
{
public class TBExtender
{
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.RegisterAttached("IsChecked",
typeof(bool),
typeof(TBExtender),
new PropertyMetadata(OnChanged));
public static bool GetIsChecked(DependencyObject obj)
{
return (bool)obj.GetValue(IsCheckedProperty);
}
public static void SetIsChecked(DependencyObject obj, bool value)
{
obj.SetValue(IsCheckedProperty, value);
}
private static void OnChanged(DependencyObject o,
DependencyPropertyChangedEventArgs args)
{
ToggleButton tb = o as ToggleButton;
if (null != tb)
tb.IsChecked = (bool)args.NewValue;
}
}
}
XAML then will look like this:
<ToggleButton Command="{Binding Path=SomeCommand}"
TBFix:TBExtender.IsChecked="{Binding Path=SomeProperty,
Mode=OneWay}" />
EDIT: The OP solution does not work, because when the button is pressed the IsChecked property is set in the code (this is the way MS implemented ToggleButton control) - setting the property removes the binding from it and so it stops working.
By using attached property we can overcome this problem because it is never assigned a value in code and so the bindings stays intact.