C # - Xamarin.Forms - Зависимость Сервис и событие - PullRequest
0 голосов
/ 21 ноября 2018

Я хотел бы получить уведомление о событии PropertyChanged, вызванном из класса MyClass, реализующего интерфейс IMyInterface.Экземпляр этого класса извлекается с помощью DependencyService.Get<IMyInterface>();

Теперь это класс (проект Android), в котором есть свойство с полем поддержки:

class MyClass : IMyInterface {

    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        private set { _isEnabled = value; OnPropertyChanged("IsEnabled"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    public void OnSomethingHappens() { //This method is called when something particular happens
        /* Some code... */
        IsEnabled = true; //The point where the property is changed
        /* ...some other code */
    }
}

Интерфейс(Проект Forms) выглядит следующим образом:

public interface IMyInterface : INotifyPropertyChanged
{
    /* code relating the interface */
}

Этот интерфейс реализует INotifyPropertyChanged, чтобы иметь возможность прослушивать изменение свойства (как видно из класса выше).Пока все хорошо.

Проблема в том, что в моем проекте Forms я регистрирую обработчик событий следующим образом:

_myService = DependencyService.Get<IMyInterface>();
_myService.PropertyChanged += (sender, e) => { /* do stuff */ };

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

Я хотел бы добавить кое-что: недавно я обнаружил, что доступ к нестатическому свойству списка с помощью DependencyService.Get<IMyInterface>().MyList бесполезен, посколькуMyList имеет размер 0, даже если этот список был заполнен внутри реализующего класса.Я решил это с помощью статического свойства.Возможно, это связано с вышеуказанной проблемой.

Я хотел бы понять, в чем я ошибаюсь, чтобы это PropertyChanged событие работало правильно.

1 Ответ

0 голосов
/ 21 ноября 2018

Хорошо, я понял, как решить эту проблему.По сути, я создал свойство с полем private static event, как показано ниже:

private static event PropertyChangedEventHandler _propertyChanged;
public PropertyChangedEventHandler PropertyChanged
{
    get { return _propertyChanged; }
    set { _propertyChanged = value; }
}

Таким образом, я мог бы заставить следующий код работать должным образом:

protected void OnPropertyChanged(string name)
{
    _propertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

Infact, _propertyChanged больше не был null, так как я подписался на событие со следующим кодом (формально идентичным тому, который был опубликован в моем вопросе, с той разницей, что я использовал свойство PropertyChanged, подкрепленное частным статическим полем _propertyChanged):

_myService = DependencyService.Get<IMyInterface>();
_myService.PropertyChanged += (sender, e) => { /* do stuff */ };

Теперь я думаю, что это было необходимо, потому что я использую DependencyService, иначе в обычном коде эта проблема не должна появляться.В любом случае, я предполагаю, является ли идея иметь свойство EventHandler, подкрепленное полем private static event, хорошей практикой кода или просто звучит странно.Но это работает, и это работает довольно хорошо.

Но, чтобы сделать все это, мне пришлось изменить это:

public interface IMyInterface : INotifyPropertyChanged
{
    /* code relating the interface */
}

на это:

public interface IMyInterface
{
    PropertyChangedEventHandler PropertyChanged { get; set; }
    /* code relating the interface */
}

Мне пришлось добавить это свойство в IMyInterface, чтобы я мог получить к нему доступ из своего кода проекта Forms.Более того, я больше не реализую INotifyPropertyChanged, потому что INotifyPropertyChanged просит меня реализовать интерфейс с:

public event PropertyChangedEventHandler PropertyChanged

внутри моего реализующего класса, но я заменил его на

private static event PropertyChangedEventHandler _propertyChanged;
public PropertyChangedEventHandler PropertyChanged
{
    get { return _propertyChanged; }
    set { _propertyChanged = value; }
}

как я показал выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...