Reputation: 25
I want to bind a button's IsEnabled
to the result of a boolean expression.
I only find quite complex solutions using converters or other methods. Is it also possible in a more simple way?
Example code:
<Button IsEnabled="{ Binding Path=IsRecordingEnabled }" />
public partial class MainWindow : Window
{
public bool IsRecording { get; set; } = false;
public string LoggingFolder { get; set; } = null;
public bool IsRecordingEnabled
{
get
{
return !IsRecording && LoggingFolder != null;
}
}
// ...
}
Obviously the Button is not updating when the expression changes. I understand that I need to notify the GUI via OnNotifyPropertyChanged
or similar. But how to do that in my case where I want to handle the boolean expression which has no set
method but is changed via the composition of IsRecording
and LoggingFolder
.
Upvotes: 1
Views: 376
Reputation: 3
You can use a ToggleButton instead of a button.
WPF:
<ToggleButton x:Name="record" Content="Record" .../>
In Main Window you can use: record.IsChecked = true/false; to set or reset the state of the ToggleButton
if (record.IsChecked == true && LoggingFolder == null)
{
//Do what you want
}
You can also use a click event
private void record_Click(object sender, RoutedEventArgs e)
{
LoggingFolder != null;
}
Upvotes: 0
Reputation: 7855
The de-facto default implementation of PropertyChanged
is:
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
You can see it has the parameter name
decorated with the attribute [CallerMemberName]
it "Allows you to obtain the method or property name of the caller to the method." (source). Which means that you can manually specify which property changed by passing in the name. This means you can tell the GUI a property changed, without having to have a setter and set it. Like so:
private bool _isRecording = false;
public bool IsRecording
{
get => _isRecording;
set
{
_isRecording = value;
// You could omit the next line, if the UI doesn't bind to this property
OnPropertyChanged();
OnPropertyChanged(nameof(IsRecordingEnabled));
}
}
Upvotes: 1
Reputation: 8743
You'll have to invoke the PropertyChanged
event when you change either IsRecording
or ReplayLogFile
. In the event args, you have to tell that the property IsRecordingEnabled
changed:
public partial class MainWindow : Window,INotifyPropertyChanged
{
private bool _isRecording = false;;
public bool IsRecording
{
get => _isRecording;
set
{
_isRecording = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRecordingEnabled)));
}
private string _replayLogFile = null;
public string ReplayLogFile
{
get => _replayLogFile;
set
{
_replayLogFile = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRecordingEnabled)));
}
}
public bool IsRecordingEnabled
{
get
{
return !IsRecording && LoggingFolder != null;
}
}
// ...
}
Upvotes: 2