简体   繁体   中英

Binding ToggleButton's IsChecked property in WP7

I have this ToggleButton in my WP7 app which I bind to a property in my ViewModel. I also have a command to the ToggleButton which does work when clicking the button.

Based on the result of that command, I set the property that is bound to the ToggleButton.IsChecked property. But no matter what I set the property to, the toggle button lives its own life and just switches between unchecked and checked. Is this expected behaviour or is this a bug?

It seems like the toggle button loses its binding when clicking on it, would this be true? The reason I want it bound is that I do not always want to change the checked state, because the logic in my command can fail, eg network is down so it cant set what I want in the back end, and so forth.

Any workaround for this problem?

Xaml:

<ToggleButton x:Name="ToggleButton" Style="{StaticResource ToggleButtonStyle}" IsChecked="{Binding IsToggleButtonChecked}, Mode=OneWay}" Command="{Binding ToggleButtonCommand, Mode=OneWay}" CommandParameter="{Binding ToggleButtonCommandParameter}"/>

The style sets the image of the button based on states. The command does logic when the button is clicked and, as said earlier, sets IsToggleButtonChecked to desired value. I have both tried OneWay and TwoWay on the IsChecked, but I can´t see the difference.

ViewModel:

public const string IsToggleButtonCheckedPropertyName = "IsToggleButtonChecked";

    private bool _isToggleButtonChecked;

    public bool IsToggleButtonChecked
    {
        get { return _isToggleButtonChecked; }

        set
        {
            if (_isToggleButtonChecked == value)
            {
                return;
            }

            _isToggleButtonChecked = value;

            RaisePropertyChanged(IsToggleButtonCheckedPropertyName);
        }
    }

This property is set each time i want to change the checked state of the ToggleButton.

Make sure the ToggleButton is being notified of any changes you make to the bound property.

XAML

<ToggleButton Click="OnClicked"
              IsChecked="{Binding IsChecked, Mode=TwoWay}" />

C#

private bool _isChecked = false;
public bool IsChecked
{
  get { return _isChecked; }
  set 
  {
    if( value != _isChecked ) {
      _isChecked = value;
      NotifyPropertyChanged( "IsChecked" );
    }
  }
}

Have your logic set IsChecked = false; in code behind to uncheck the button.

For others that might wonder about the same: I solved this by using TwoWay mode as Praetorian said, but let it change its value by itself for the normal scenarios. The times I want it to stay in the same state as before I clicked it, I just set the bindable value to the wanted value. Also, I have another variable that keeps track of the isChecked state that is not binded. By doing that, I can check and set the value accordingly, and don't mess up the visual checked state. This works, but its not a perfect way to do it.

Without seeing any code, my first instinct would be to verify that the ViewModel implements INotifyPropertyChanged, and that the setter of the property that is bound to IsEnabled is firing the property changed event when it's set.

using System.ComponentModel;

class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool _enableCheckBox;
    public bool EnableCheckBox
    {
        get { return _enableCheckBox }
        set 
        {
            _enableCheckBox = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("EnableCheckBox"));
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM