简体   繁体   中英

Binding Button.IsEnabled to Boolean Property

I have a boolean property that looks at several checkboxes and returns true if any of them are checked. I would like to enable a button if any checkboxes are checked (property returns true).

Currently I have the following:

  • The data context set

     public MainWindow() { InitializeComponent(); this.DataContext = this; } 
  • The button binding set

     <Button Name="button" IsEnabled="{Binding ButtonEnabled}">Apply</Button> 
  • The property

     public bool ButtonEnabled { get { if(checkboxes_enabled) return true; else return false; } } 

I have verified that the property is updating as it is supposed to, so it's narrowed down to a binding issue. I have also tried data triggers within the button:

<Button Name="button" Content="Apply">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ButtonEnabled}" Value="True">
                    <Setter Property="IsEnabled" Value="True"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding ButtonEnabled}" Value="False">
                    <Setter Property="IsEnabled" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Two things:

You need INotifyPropertyChanged if you are making updates to a property that is bound.

public class MyClass
{
    private bool _buttonEnabled;
    public bool ButtonEnabled
    {
        get
        {
            return _buttonEnabled;
        }
        set
        {
            _buttonEnabled = value;
            OnPropertyChanged();
        }
    }

    public SetButtonEnabled()
    {
        ButtonEnabled = checkboxes_enabled;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged<T>([CallerMemberName]string caller = null) 
    {
        var handler = PropertyChanged;
        if (handler != null) 
        {
            handler(this, new PropertyChangedEventArgs(caller));
        }
    }
}

You should also not have two triggers, and just use a default value.

<Button Name="button" Content="Apply">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="IsEnabled" Value="True"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ButtonEnabled}" Value="False">
                    <Setter Property="IsEnabled" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

you need to add the following code to implement INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

then call OnPropertyChanged from the property setter

I Would suggest binding the button to a command rather then an event, This way you can just set the command's "canexecute" property to false and disable the whole command that will intern disable the button for you.

I recommend the below tutorial to get a good understanding on WPF commands and how to use them, Once you understand how they work I find they are extremely useful.

http://www.codeproject.com/Articles/274982/Commands-in-MVVM#hdiw1

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