繁体   English   中英

C#-Xamarin.Forms-依赖服务和事件

[英]C# - Xamarin.Forms - Dependency Service and event

我想通过从实现接口IMyInterface MyClass类引发的PropertyChanged事件得到通知。 使用DependencyService.Get<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结果为null,这意味着该事件永远不会触发。

我想添加一点:最近,我体验到使用DependencyService.Get<IMyInterface>().MyList访问非静态列表属性DependencyService.Get<IMyInterface>().MyList毫无用处,因为MyList的大小为0 ,即使该列表已满在实现类中。 我使用静态属性解决了这个问题。 也许这与上面的问题有关。

我想了解我为了使此PropertyChanged事件正确运行而犯的错误。

好的,我想出了解决方法。 基本上,我创建了一个具有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));
}

实际上, _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; }
}

正如我上面暴露的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM