NotifyPropertyChanged 未在派生中触发 class
NotifyPropertyChanged not firing in derived class
我有这3个类
[AddINotifyPropertyChangedInterface]
public abstract class BaseViewModel
{
}
public abstract class XXXViewModelBase : BaseViewModel
{
public int SelectedAreaId { get; set; }
}
public class XXXSelectorViewModel : XXXViewModelBase
{
//public new int SelectedAreaId { get => base.SelectedAreaId; set => base.SelectedAreaId = value; }
public void OnSelectedAreaIdChanged()
{
// Does not fire
}
}
使用如图所示的代码,当 SelectedAreaId
更改时 OnSelectedAreaIdChanged
不会触发。如果我取消注释代码,那么 OnSelectedAreaIdChanged
会触发。
这是预期的行为吗?除了我这样做的方法之外,还有其他解决方法吗?
这是你想要的吗?
public class BaseViewModel : INotifyPropertyChanged
{
/// <summary>
/// Worker function used to set local fields and trigger an OnPropertyChanged event
/// </summary>
/// <typeparam name="T">Parameter class</typeparam>
/// <param name="backingStore">Backing field referred to</param>
/// <param name="value">New value</param>
/// <param name="propertyName">Property that this value is applied to </param>
/// <param name="onChanged">Event handler to invoke on value change</param>
/// <param name="onChanging">Event handler to invoke on value changing</param>
/// <returns></returns>
protected bool SetProperty<T>(
ref T backingStore, T value,
[CallerMemberName] string propertyName = "",
Action onChanged = null,
Action<T> onChanging = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value)) return false;
onChanging?.Invoke(value);
OnPropertyChanging(propertyName);
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanging implementation
/// <summary>
/// INotifyPropertyChanging event handler
/// </summary>
public event PropertyChangingEventHandler PropertyChanging;
/// <summary>
/// INotifyOnPropertyChanging implementation
/// </summary>
/// <param name="propertyName">Class property that is changing</param>
protected void OnPropertyChanging([CallerMemberName] string propertyName = "")
{
var changing = PropertyChanging;
changing?.Invoke(this, new PropertyChangingEventArgs(propertyName));
}
#endregion
#region INotifyPropertyChanged
/// <summary>
/// INotifyPropertyChanged event handler
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// INotifyPropertyChanged implementation
/// </summary>
/// <param name="propertyName">Class property that has changed</param>
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
使用示例:
public class SomeViewModel: BaseViewModel
{
private int _someValue;
public int SomeValue
{
get => _someValue;
set => SetProperty(ref _someValue, value);
}
}
是的,这是预期的行为,因为 Fody 不支持这一点。 More Info Here
我有这3个类
[AddINotifyPropertyChangedInterface]
public abstract class BaseViewModel
{
}
public abstract class XXXViewModelBase : BaseViewModel
{
public int SelectedAreaId { get; set; }
}
public class XXXSelectorViewModel : XXXViewModelBase
{
//public new int SelectedAreaId { get => base.SelectedAreaId; set => base.SelectedAreaId = value; }
public void OnSelectedAreaIdChanged()
{
// Does not fire
}
}
使用如图所示的代码,当 SelectedAreaId
更改时 OnSelectedAreaIdChanged
不会触发。如果我取消注释代码,那么 OnSelectedAreaIdChanged
会触发。
这是预期的行为吗?除了我这样做的方法之外,还有其他解决方法吗?
这是你想要的吗?
public class BaseViewModel : INotifyPropertyChanged
{
/// <summary>
/// Worker function used to set local fields and trigger an OnPropertyChanged event
/// </summary>
/// <typeparam name="T">Parameter class</typeparam>
/// <param name="backingStore">Backing field referred to</param>
/// <param name="value">New value</param>
/// <param name="propertyName">Property that this value is applied to </param>
/// <param name="onChanged">Event handler to invoke on value change</param>
/// <param name="onChanging">Event handler to invoke on value changing</param>
/// <returns></returns>
protected bool SetProperty<T>(
ref T backingStore, T value,
[CallerMemberName] string propertyName = "",
Action onChanged = null,
Action<T> onChanging = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value)) return false;
onChanging?.Invoke(value);
OnPropertyChanging(propertyName);
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanging implementation
/// <summary>
/// INotifyPropertyChanging event handler
/// </summary>
public event PropertyChangingEventHandler PropertyChanging;
/// <summary>
/// INotifyOnPropertyChanging implementation
/// </summary>
/// <param name="propertyName">Class property that is changing</param>
protected void OnPropertyChanging([CallerMemberName] string propertyName = "")
{
var changing = PropertyChanging;
changing?.Invoke(this, new PropertyChangingEventArgs(propertyName));
}
#endregion
#region INotifyPropertyChanged
/// <summary>
/// INotifyPropertyChanged event handler
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// INotifyPropertyChanged implementation
/// </summary>
/// <param name="propertyName">Class property that has changed</param>
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
使用示例:
public class SomeViewModel: BaseViewModel
{
private int _someValue;
public int SomeValue
{
get => _someValue;
set => SetProperty(ref _someValue, value);
}
}
是的,这是预期的行为,因为 Fody 不支持这一点。 More Info Here