我有一个WPF MVVM应用程序。我有一个名为MainWindowViewModel
的班级和一个名为TileMenuViewModel
的班级,这两个班级都来自BaseViewModel
。所有基础都是实现INotifyPropertyChanged
和INotifyDataErrorInfo
,同时保留Dictionary<string, List<string>>
个错误以进行验证。
在我的MainWindowViewModel
中,我实例化了一个
private TileMenuViewModel _tileMenuViewModel = new TileMenuViewModel();
在我的TileMenuViewModel
中,我有一个
public event Action NavToCampaings = new delegate {};
现在在MainWindowViewModel
构造函数中,我订阅了这个事件:
_tileMenuViewModel.NavToCampaings += OnNavToCampaigns;
但是,当我在某个时候从TileMenuViewModel
调用该事件时,例如NavToCampaigns();
我的订阅事件(OnNavToCampaigns
的{{1}})未被调用。当我使用断点进行调试时,我可以看到调用MainWindowViewModel
事件Action,但其值为null。调试器在通过我实例化NavToCampaigns();
的MainWindowViewModel构造时也不会输入TileMenuViewModel
。但是,我的其余程序按照我的意图工作,我看到Tile Menu工作。
对于我的生活,我无法弄清楚我做错了什么。有任何想法吗?为简洁起见,这是我的三个班级:
MainWindowViewModel.cs
TileMenuViewModel
TileMenuViewModel.cs
namespace MyApp.Main
{
public class MainWindowViewModel : BaseViewModel
{
private string _windowsUser = WindowsIdentity.GetCurrent().Name;
private TileMenuViewModel _tileMenuViewModel = new TileMenuViewModel();
private CmpCampaignListViewModel _cmpCampaignListViewModel = new CmpCampaignListViewModel();
private NapTransferCampaignListViewModel _ntCampaignListViewModel = new NapTransferCampaignListViewModel();
public string WindowsUser { get { return _windowsUser; } }
public string WindowTitle { get; set; }
private BaseViewModel _currentViewModel;
public BaseViewModel CurrentViewModel
{
get { return _currentViewModel; }
set { SetProperty(ref _currentViewModel, value); }
}
public MainWindowViewModel()
{
WindowTitle = String.Format("MyApp - {0}", WindowsUser);
NavCommand = new RelayCommand<string>(OnNav);
AddNewCmpCampaignCommand = new RelayCommand(OnAddNewCmpCampaign);
CurrentViewModel = _tileMenuViewModel;
_tileMenuViewModel.NavToCampaings += OnNavToCampaigns;
}
public RelayCommand<string> NavCommand { get; private set; }
public RelayCommand AddNewCmpCampaignCommand { get; private set; }
public void OnNav(string destination)
{
switch (destination)
{
case "CmpCampaignList":
CurrentViewModel = _cmpCampaignListViewModel;
break;
case "NtCampaignList":
CurrentViewModel = _ntCampaignListViewModel;
break;
case "TileMenu":
CurrentViewModel = _tileMenuViewModel;
break;
default:
CurrentViewModel = _tileMenuViewModel;
break;
}
}
public void OnAddNewCmpCampaign()
{
var editCampaignWindow = new AddEditCmpCampaignWindow();
editCampaignWindow.Show();
}
private void OnNavToCampaigns()
{
CurrentViewModel = _cmpCampaignListViewModel;
//OnNav("CmpCampaignList");
}
}
}
BaseViewModel.cs
namespace MyApp.Main
{
public class TileMenuViewModel : BaseViewModel
{
public TileMenuViewModel()
{
NavToCampaignsCommand = new RelayCommand(OnNavToCampaigns);
}
public RelayCommand NavToCampaignsCommand { get; private set; }
public event Action NavToCampaings = delegate { };
private void OnNavToCampaigns()
{
NavToCampaings();
}
}
}
答案 0 :(得分:0)
修改强>
我解释了为什么它不起作用:我在视图中有一个新的TileMenuViewModel
实例,我用它;在我使用viewmodel进行测试后,我忘了它。它将DataContext
设置为触发事件的新实例,MainWindowViewModel
正在侦听其自己的TileMenuViewModel
实例的事件。所以我只是删除了这一行:
DataContext = new TileMenuViewModel();
来自我的TileMenuView
并将我的活动连线了。我会把这个帖子留给任何可能会觉得有用的人。
我仍然想知道将此事件用作静态会不会更好或更坏?
原始答案:
我最后通过将事件标记为静态来解决这个问题。即:
public static event Action NavToCampaings = delegate { };
当然,我在不使用类实例的情况下订阅了该事件:
TileMenuViewModel.NavToCampaings += OnNavToCampaigns;
但是,我仍然想知道为什么我无法将此事件系统作为实例成员使用该事件;如果使用事件静态会造成任何问题(或者如果它只是一个不好的做法?)
任何解释都会被贬低。