Я хочу привязать кнопку IsEnabled к результату логического выражения.

Я только нахожу довольно сложные решения с помощью конвертеров или других методов. Можно ли еще проще?

Пример кода:

<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;
        }
    }

    // ...
}

Очевидно, что кнопка не обновляется при изменении выражения. Я понимаю, что мне нужно уведомить графический интерфейс через OnNotifyPropertyChanged или подобное. Но как это сделать в моем случае, когда я хочу обработать логическое выражение, которое не имеет метода set, но изменяется с помощью композиции IsRecording и LoggingFolder.

1
marcel 8 Окт 2020 в 14:59

3 ответа

Лучший ответ

Вам нужно будет вызвать событие PropertyChanged, когда вы измените IsRecording или ReplayLogFile. В случае аргументов вы должны указать, что свойство IsRecordingEnabled изменилось:

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;
        }
    }

    // ...
}
2
SomeBody 8 Окт 2020 в 12:03

Вы можете использовать ToggleButton вместо кнопки.

WPF :

<ToggleButton x:Name="record" Content="Record" .../>

В главном окне вы можете использовать: record.IsChecked = true / false; для установки или сброса состояния ToggleButton

if (record.IsChecked == true && LoggingFolder == null)
{
    //Do what you want
}

Вы также можете использовать событие щелчка

private void record_Click(object sender, RoutedEventArgs e)
{
    LoggingFolder != null;
}
0
Rquente 8 Окт 2020 в 12:54

фактическая реализация по умолчанию PropertyChanged:

protected void OnPropertyChanged([CallerMemberName] string name = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

Вы можете видеть, что у него есть параметр name, украшенный атрибутом [CallerMemberName], он "позволяет вам получить метод или имя свойства вызывающего метода". (источник ). Это означает, что вы можете вручную указать, какое свойство изменилось, передав имя. Это означает, что вы можете сообщить графическому интерфейсу об изменении свойства без необходимости иметь сеттер и устанавливать его. Вот так:

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));
    }
}
1
MindSwipe 8 Окт 2020 в 12:37