[英]C# - Xamarin.Forms - Dependency Service and event
I would like to be notified with a PropertyChanged event raised from a class MyClass
implementing an interface IMyInterface
. 我想通过从实现接口
IMyInterface
MyClass
类引发的PropertyChanged事件得到通知。 The instance of this class is retrieved with DependencyService.Get<IMyInterface>();
使用
DependencyService.Get<IMyInterface>();
检索此类的实例DependencyService.Get<IMyInterface>();
Now, this is the class (Android project), in which there is a property with a backing field: 现在,这是类(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 */
}
}
The interface (Forms project) looks like this: 接口(Forms项目)如下所示:
public interface IMyInterface : INotifyPropertyChanged
{
/* code relating the interface */
}
This interface is implementing INotifyPropertyChanged
in order to have the possibility to listen to a property change (as seen in the class above). 此接口正在实现
INotifyPropertyChanged
,以便可以侦听属性更改(如上类所示)。 So far, so good. 到现在为止还挺好。
The problem is when, in my Forms project, I register an event handler with this: 问题是,在我的Forms项目中,当我使用以下命令注册事件处理程序时:
_myService = DependencyService.Get<IMyInterface>();
_myService.PropertyChanged += (sender, e) => { /* do stuff */ };
But when the property in my implementing class changes, PropertyChanged
results null, and this means that the event is never fired. 但是,当实现类中的属性发生更改时,
PropertyChanged
结果为null,这意味着该事件永远不会触发。
I would like to add a little thing: recently, I experienced that accessing a non-static list property with DependencyService.Get<IMyInterface>().MyList
was useless, since MyList
resulted to be of size 0
, even if this list was filled inside the implementing class. 我想添加一点:最近,我体验到使用
DependencyService.Get<IMyInterface>().MyList
访问非静态列表属性DependencyService.Get<IMyInterface>().MyList
毫无用处,因为MyList
的大小为0
,即使该列表已满在实现类中。 I solved this using a static property. 我使用静态属性解决了这个问题。 Maybe this is related to the issue above.
也许这与上面的问题有关。
I would like to understand what I am mistaking in order to have this PropertyChanged
event working correctly. 我想了解我为了使此
PropertyChanged
事件正确运行而犯的错误。
Ok, I figured out how to solve this. 好的,我想出了解决方法。 Basically, I created a property with a
private static event
backing field, as follows: 基本上,我创建了一个具有
private static event
支持字段的属性,如下所示:
private static event PropertyChangedEventHandler _propertyChanged;
public PropertyChangedEventHandler PropertyChanged
{
get { return _propertyChanged; }
set { _propertyChanged = value; }
}
This way, I could have the following code working properly: 这样,我可以使以下代码正常工作:
protected void OnPropertyChanged(string name)
{
_propertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
Infact, _propertyChanged
was not null
anymore, since I subscribed to the event with the following code (formally identical to the one posted on my question, with the difference that I used the PropertyChanged
property backed with the private static field _propertyChanged
): 实际上,
_propertyChanged
不再为null
,因为我使用以下代码订阅了该事件(与我的问题上发布的代码完全相同,所不同的是,我使用的PropertyChanged
属性带有私有静态字段_propertyChanged
):
_myService = DependencyService.Get<IMyInterface>();
_myService.PropertyChanged += (sender, e) => { /* do stuff */ };
Now I think that this was necessary because I am using DependencyService
, otherwise, in normal code, this issue should not come out. 现在,我认为这是必要的,因为我正在使用
DependencyService
,否则,在普通代码中,此问题不应出现。 Anyway, I am guessing if the idea of having a EventHandler
property backed with a private static event
field is a good code practice or just sounds weird. 无论如何,我猜测将
EventHandler
属性与private static event
字段作为后盾的想法是好的代码实践还是听起来很奇怪。 But it works, and it works pretty good. 但是它有效,并且效果很好。
But, in order to do all of this, I had to change this: 但是,为了完成所有这些操作,我必须更改此设置:
public interface IMyInterface : INotifyPropertyChanged
{
/* code relating the interface */
}
to this: 对此:
public interface IMyInterface
{
PropertyChangedEventHandler PropertyChanged { get; set; }
/* code relating the interface */
}
I had to add that property in IMyInterface
so that I could access it from my Forms project code. 我必须在
IMyInterface
添加该属性,以便可以从Forms项目代码中访问它。 Moreover, I no more implement INotifyPropertyChanged
, because INotifyPropertyChanged
asks me to implement the interface with a: 而且,我不再实现
INotifyPropertyChanged
,因为INotifyPropertyChanged
要求我使用以下方法实现接口:
public event PropertyChangedEventHandler PropertyChanged
inside my implementing class, but I substituted it with 在我的实现类中,但是我用
private static event PropertyChangedEventHandler _propertyChanged;
public PropertyChangedEventHandler PropertyChanged
{
get { return _propertyChanged; }
set { _propertyChanged = value; }
}
as I exposed above. 正如我上面暴露的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.