编辑:请参阅课程结构。 INotifyPropertyChanged在ComMethodA情况下工作正常,并按预期触发事件。为什么它在ComMethodB情况下不起作用?
编辑2: 请参阅视图模型代码。
在我的应用程序中,我有几个视图和ViewModel。 所有ViewModel都继承自ViewModelBase,它创建了我的模型的单例对象,我们将其称为MainModel,具有以下结构:
public class MainModel : INotifyPropertyChanged
{
public string Name {get; set; }
public List<ISystem> SystemsList{get;set;}
public IComMethod ComMethodA {get;set;} // TEST 1
public MainModel()
{
ComMethodA = new ClassC();
// let's assume that the other props are initialized
}
}
public class System: ISystem, INotifyPropertyChanged
{
public IComMethod ComMethodB {get;set;} // TEST 2
public System()
{
ComMethodB = new classC(); // classC implements INotifyPropertyChanged, IComMethod
}
}
public class ClassC() : IComMethod, INotifyPropertyChanged
{
public bool isOpen {get;set;}
public ClassC()
{
// ctor..
}
}
ViewModelA:
ctor()
{
MainModel.SystemsList[0].ComMethodB.PropertyChanged += ComMethodB_PropertyChanged;
MainModel.ComMethodA.PropertyChanged += ComMethodA_PropertyChanged;
}
private void ComMethodB_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
MessageBox.Show("TextB");
}
private void ComMethodA_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
MessageBox.Show("TextA");
}
ViewModel B:
MainModel.ComMethodA.isOpen = true; // FIRES event in ViewModelA
MainModel.SystemsList[0].ComMethodB.isOpen = true; // DOESN'T fires event in ViewModelA
在ViewModelA中,我实现了TEST 1&amp; amp;测试2属性。 在ViewModelB中,我正在改变&#39; isOpen&#39;属性。
问题是该事件仅在ComMethodA&#39;情景,但我希望它在“ComMethodB&#39;场景。
由于
答案 0 :(得分:2)
我怀疑问题出在您没有发布的代码中。如果我不得不猜测,我说它与ViewModelBase类中的MainModel单例有关 - 也许ViewModelA / B正在获得MainModel的不同实例?
我填写了问题代码中的空白,它似乎对我有用。 注意:由于名称空间冲突,我将类System重命名为Systems。
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfApp9
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Setup the ViewModels
var vmA = new ViewModelA();
var vmB = new ViewModelB();
// Test ViewModelB
vmB.DoIt();
}
}
public class MainModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
this.OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName]string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
#region Property List<ISystem> SystemsList
private List<ISystem> _SystemsList;
public List<ISystem> SystemsList { get { return _SystemsList; } set { SetProperty(ref _SystemsList, value); } }
#endregion
#region Property IComMethod ComMethodA
private IComMethod _ComMethodA;
public IComMethod ComMethodA { get { return _ComMethodA; } set { SetProperty(ref _ComMethodA, value); } }
#endregion
public MainModel()
{
SystemsList = new List<ISystem>() { new Systems() };
ComMethodA = new ClassC();
}
}
public interface ISystem
{
IComMethod ComMethodB { get; set; }
}
public interface IComMethod : INotifyPropertyChanged
{
bool isOpen { get; set; }
}
public class Systems : ISystem, INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
this.OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName]string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
#region Property IComMethod ComMethodB
private IComMethod _ComMethodB;
public IComMethod ComMethodB { get { return _ComMethodB; } set { SetProperty(ref _ComMethodB, value); } }
#endregion
public Systems()
{
ComMethodB = new ClassC();
}
}
public class ClassC : IComMethod, INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
this.OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName]string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
#region Property bool isOpen
private bool _isOpen;
public bool isOpen { get { return _isOpen; } set { SetProperty(ref _isOpen, value); } }
#endregion
}
public class ViewModelBase : INotifyPropertyChanged
{
public static MainModel MainModel { get; } = new MainModel();
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
this.OnPropertyChanged(name);
return true;
}
protected void OnPropertyChanged([CallerMemberName]string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
}
public class ViewModelA : ViewModelBase
{
public ViewModelA()
{
MainModel.SystemsList[0].ComMethodB.PropertyChanged += ComMethodB_PropertyChanged;
MainModel.ComMethodA.PropertyChanged += ComMethodA_PropertyChanged;
}
private void ComMethodB_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MessageBox.Show("TextB");
}
private void ComMethodA_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MessageBox.Show("TextA");
}
}
public class ViewModelB : ViewModelBase
{
public ViewModelB()
{
}
public void DoIt()
{
MainModel.ComMethodA.isOpen = true; // this fired off the "TextA" messagebox
MainModel.SystemsList[0].ComMethodB.isOpen = true; // this fired off the "TextB" messagebox
}
}
}