WPF应用程序 - 调用事件操作时不会触发侦听方法

时间:2015-12-22 09:14:23

标签: c# wpf events mvvm action

我有一个WPF MVVM应用程序。我有一个名为MainWindowViewModel的班级和一个名为TileMenuViewModel的班级,这两个班级都来自BaseViewModel。所有基础都是实现INotifyPropertyChangedINotifyDataErrorInfo,同时保留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();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

修改 我解释了为什么它不起作用:我在视图中有一个新的TileMenuViewModel实例,我用它;在我使用viewmodel进行测试后,我忘了它。它将DataContext设置为触发事件的新实例,MainWindowViewModel正在侦听其自己的TileMenuViewModel实例的事件。所以我只是删除了这一行:

DataContext = new TileMenuViewModel();

来自我的TileMenuView并将我的活动连线了。我会把这个帖子留给任何可能会觉得有用的人。

我仍然想知道将此事件用作静态会不会更好或更坏?

原始答案:

我最后通过将事件标记为静态来解决这个问题。即:

public static event Action NavToCampaings = delegate { };

当然,我在不使用类实例的情况下订阅了该事件:

TileMenuViewModel.NavToCampaings += OnNavToCampaigns;

但是,我仍然想知道为什么我无法将此事件系统作为实例成员使用该事件;如果使用事件静态会造成任何问题(或者如果它只是一个不好的做法?)

任何解释都会被贬低。