INotifyPropertyChanged через слои косвенности - PullRequest
0 голосов
/ 07 марта 2020

Это может быть проблема XY. Пожалуйста, не стесняйтесь, скажите мне, если я здесь совершенно неосновный.

Во-первых, упрощенный пример ситуации, о которой я думаю.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace XXXXXXX
{
    public class AbstractOperation : INotifyPropertyChanged
    {
        public enum OpState { Init, Running, Aborted, Completed, Errored };
        OpState privateOperationState;
        public OpState OperationState
        {
            get => privateOperationState;
            private set
            {
                if(privateOperationState!=value)
                {
                    privateOperationState = value;
                    OnPropertyChanged();
                }
            }
        }

        public bool IsRunning => OperationState == OpState.Running;

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

    public class BackgroundOperator
    {
        AbstractOperation whatever;

        public bool IsRunning => whatever.IsRunning;
        public AbstractOperation.OpState OperationState => whatever.OperationState;
    }

}

AbstractOperation is быть базовым классом, представляющим некоторую многошаговую операцию, выполнение которой занимает значительное время. Он будет отображать статус своей операции через некоторые свойства.

BackgroundOperation - это класс, который будет принимать AbstractOperation и запускать его в фоновом потоке, проходя через некоторые свойства состояния. Я хочу иметь возможность привязать некоторые свойства элемента пользовательского интерфейса к этим операциям, чтобы, например, определенный элемент управления был отключен во время выполнения операции. Я понимаю, что интерфейс INotifyPropertyChanged необходим для работы таких привязок.

Если я реализую событие PropertyChange только для одного свойства, подобного этому, будет ли уведомление автоматически покрывать другие свойства, которые ссылаются на это свойство в их теле? Работает ли он только внутри класса или все еще работает с другим классом, которому принадлежит экземпляр уведомляющего класса? Нужно ли делать какой-то специальный код, чтобы связать ссылающиеся свойства с уведомлением исходного свойства? Или я здесь глубоко в XY и должен реализовать какой-то другой способ привязки элементов управления пользовательского интерфейса к состоянию моей операции?

1 Ответ

0 голосов
/ 07 марта 2020

Если я реализую событие PropertyChange только для одного свойства, подобного этому, будет ли уведомление автоматически охватывать другие свойства, которые ссылаются на это свойство в своем теле?

Что произошло, когда вы его попробовали ? Получили ли вы уведомление об изменении свойства для других свойств?

Работает ли оно только внутри класса или все еще работает с другим классом, которому принадлежит экземпляр уведомляющего класса?

Он вообще этого не делает, поэтому не будет делать это ни в каком другом классе.

Уведомление об изменении свойства не является магическим c. Он просто вызывает событие, устанавливая значение имени в объекте args события равным тому, которое вы передали методу OnPropertyChanged() (в данном случае, неявно через атрибут [CallerMemberName]).

Все, что сказано Использование таких свойств не обязательно лучший способ справиться с отключением команд. Вы не говорите, какой API вы на самом деле используете, но распространенным, который использует этот тип шаблона, является WPF. Он использует ICommand привязки для команд. Метод ICommand.CanExecute() должен использоваться, чтобы указать, является ли команда действительной в данный момент времени. ICommand.CanExecuteChanged следует повышать при изменении значения этого метода. Обычно это делается любым кодом, начинающим операцию, или изменяет состояние, которое делает команду недопустимой в это время. После этого тот же код изменит состояние CanExecute() на действительное.

Точный механизм изменения состояния команды и вызова ее события зависит от того, как вы реализуете команду. Есть много примеров, которые вы должны рассмотреть. Посмотрите, что работает лучше для вас.

Если вы используете какой-то другой API, он может иметь или не иметь аналогичный механизм. Невозможно узнать, каким будет лучший ответ в этом отношении, поскольку эта информация недоступна в вашем вопросе.

...