Обслуживание диапазонов байта WSGI

Основная проблема в вашем коде заключается в том, что System.Windows.Media.SolidColorBrush не переопределяет метод Equals(), и поэтому ваше выражение Background == Brushes.Black никогда не будет true. Так как вы создаете явные новые экземпляры объекта SolidColorBrush, а оператор == просто сравнивает ссылки на экземпляры, сравнение между значением кисти и встроенным экземпляром Brushes.Black всегда терпит неудачу.

Самый простой способ исправить код - это просто использовать фактические Brushes экземпляры:

private void Timer_Tick(object sender, System.EventArgs e)
{
    if (Background == Brushes.Black)
    {
        Background = Brushes.White;
        Title = "White";
    }
    else
    {
        Background = Brushes.Black;
        Title = "Black";
    }
}

Затем, когда вы сравниваете ссылки на экземпляры, они на самом деле сравнимы, и вы обнаружите «черное» состояние по желанию.

Я отмечу, что, поскольку вы также не повышаете значение PropertyChanged для изменения свойства Title, эта привязка также не будет работать должным образом.

1128 За то, что оно того стоит, я бы вообще избежал вашего замысла. Во-первых, при просмотре объектов модели следует избегать использования специфичных для пользовательского интерфейса типов. Конечно, это будет включать тип Brush. Возможно, это также включает в себя DispatcherTimer, так как он существует в обслуживании UI. Помимо этого, DispatcherTimer является относительно неточным таймером, и, хотя он существует, главным образом, для того, чтобы иметь таймер, который вызывает его событие Tick в потоке диспетчера, которому принадлежит таймер, поскольку WPF автоматически собирает события изменения свойств из любого другого потока в поток пользовательского интерфейса, он не так полезен в этом примере.

Вот версия вашей программы, которая IMHO больше соответствует типичным практикам программирования WPF:

class MainViewModel : NotifyPropertyChangedBase
{
    private string _title;
    public string Title
    {
        get { return _title; }
        set { _UpdateField(ref _title, value); }
    }

    private bool _isBlack;
    public bool IsBlack
    {
        get { return _isBlack; }
        set { _UpdateField(ref _isBlack, value, _OnIsBlackChanged); }
    }

    private void _OnIsBlackChanged(bool obj)
    {
        Title = IsBlack ? "Black" : "White";
    }

    public MainViewModel()
    {
        IsBlack = true;
        _ToggleIsBlack(); // fire and forget
    }

    private async void _ToggleIsBlack()
    {
        while (true)
        {
            await Task.Delay(TimeSpan.FromMilliseconds(100));
            IsBlack = !IsBlack;
        }
    }
}

Этот класс модели представления использует базовый класс, который я использую для всех моих моделей представления, поэтому я не нужно переопределять INotifyPropertyChanged все время:

class NotifyPropertyChangedBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void _UpdateField(ref T field, T newValue,
        Action onChangedCallback = null,
        [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer.Default.Equals(field, newValue))
        {
            return;
        }

        T oldValue = field;

        field = newValue;
        onChangedCallback?.Invoke(oldValue);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Вы заметите, что класс модели представления не имеет никакого поведения, специфичного для пользовательского интерфейса. Он будет работать с любой программой, WPF или другой, при условии, что эта программа способна реагировать на события PropertyChanged и использовать значения в модели представления.

Чтобы сделать эту работу, XAML становится несколько более многословным:


  
    
  
  
    
      
        
        
          
            
          
        
      
    
  

(Примечание: я явно назвал http://schemas.microsoft.com/netfx/2007/xaml / presentation Пространство имен XML для использования с элементом