【问题标题】:WPF MVVM Light DataGrid and separate Add Item ViewWPF MVVM Light DataGrid 和单独的 Add Item View
【发布时间】:2013-01-27 04:12:13
【问题描述】:

我正在学习 WPF 和 MVVM,我正在尝试制作一个程序,该程序具有一个 DataGrid 和一个按钮,该按钮通过使用可以向 DataGrid 添加项目的命令打开另一个表单。

问题是我不确定应该如何使用视图模型来实现这一点。我有 1 个视图模型,用于我的 DataGrid 表单,它可以正常工作,并且正在使用存储库从实体框架中检索数据。

当我按下添加按钮时,是否可以从“添加表单”中添加一个对象并让它以另一个表单自动出现在 DataGrid 中,或者我是否需要在 DataGrid 上执行一些刷新操作?我在我的视图模型中使用了可观察的集合,并且我在视图模型的集合参数中实现了 OnPropertyChange 功能。

据我所知,当我将某些东西放入存储库时,每个从中获取数据的视图模型都应该被刷新......虽然我不确定是否应该编写一些消息代码来让它工作。

我对此感到很困惑,我希望有人可以在这里阐明... 提前致谢。如果我错过了提及某些内容,请告诉我,我会添加它:)

编辑: 这就是我注册模型的方式:

SimpleIoc.Default.Register<ParentsListViewModel>();
SimpleIoc.Default.Register<EditParentViewModel>();

这就是我注册我的存储库的方式:

SimpleIoc.Default.Register<IParentsRepository, ParentsRepository>();

这就是我检索 ViewModel 实例的方式:

ParentsListViewModel parentsListViewModelInstance =  ServiceLocator.Current.GetInstance<ParentsListViewModel>();
EditParentViewModel editParentViewModelInstance = ServiceLocator.Current.GetInstance<EditParentViewModel>();

ParentsListViewModel 是我的 DataGrid ViewModel,而 EditParentViewModel 是用于在存储库中添加/编辑记录的模型。 服务定位器自动传递存储库的实例,所以我不知道它如何将存储库的实例传递给 ViewModel。它是否通过相同的实例?

【问题讨论】:

    标签: wpf entity-framework mvvm datagrid mvvm-light


    【解决方案1】:

    当您向存储库添加内容时,视图模型不会自动刷新。

    所有 observable 集合所做的只是在向可观察集合添加/删除新项目时通知 UI(粗略地说)。 INotifyPropertyChange 所做的只是通知 UI 特定属性已更改。

    你有几个选择来获得你想要的工作(如果我理解正确的话):

    • 您可以在添加项目时刷新整个可观察集合
    • 您可以让存储库在添加新项目时通过事件通知您的数据网格视图模型 - 然后您的数据网格视图模型可以更新其可观察集合
    • 您可以让 Add Form 视图模型与 Data Grid 视图模型对话,并在添加新项目时告诉它 - 在这种情况下,您需要某种机制来将信息从一个视图模型编组到另一个视图模型。李>

    这有帮助吗?

    编辑 2013 年 2 月 12 日 17:30 GMT:

    这是选项 2 的一个非常快速而肮脏的示例。它要求在 2 个视图模型之间共享相同的存储库实例 - 在这种情况下,我已将其注入到构造函数中。

    public interface IParentsRepository{
        event EventHandler<MyItemAddedEventArgs> ItemAdded;     
    
        //your normal interface implementation here
    }
    
    public class ParentsRepository : IParentsRepository
    {
        public event EventHandler<MyItemAddedEventArgs> ItemAdded;
    
        public List<MyItem> GetAllItems()
        {
            //logic that returns all your items here
            return new List<MyItem>();
        }
    
        public void AddItem(MyItem item)
        {
            //logic that adds you item here
    
            //fire the item added event
            OnItemAdded(item);
        }
    
        private void OnItemAdded(MyItem item)
        {
            if(ItemAdded != null)
                ItemAdded(this, new MyItemAddedEventArgs(item));
        }
    }
    
    public class MyItemAddedEventArgs : EventArgs
    {
        public MyItemAddedEventArgs(MyItem itemAdded)
        {
    
        }
    
        public MyItem ItemAdded { get; set; }
    }
    
    public class MyItem
    {
        public string SomeProperty { get; set; }    
    }
    
    public class MyDataGridViewModel
    {
        private readonly IParentsRepository _parentsRepository;
    
        public MyDataGridViewModel(IParentsRepository parentsRepository)
        {
            _parentsRepository = parentsRepository;
            _parentsRepository.ItemAdded += _parentsRepository_ItemAdded;
    
            var myItems = _parentsRepository.GetAllItems();
            MyItems = new ObservableCollection<MyItem>(myItems);
        }
    
        void _parentsRepository_ItemAdded(object sender, MyItemAddedEventArgs e)
        {
            if(!MyItems.Contains(e.ItemAdded))
                MyItems.Add(e.ItemAdded);
        }
    
        public ObservableCollection<MyItem> MyItems { get; set; }
    }
    
    public class MyAddItemViewModel
    {
        private readonly IParentsRepository _parentsRepository;
    
        public MyAddItemViewModel(IParentsRepository parentsRepository)
        {
            _parentsRepository = parentsRepository;
        }
    
        //your logic to add an item here
    }
    

    这个方法可以很容易地调整为方法 1,这样当 _parentsRepository_ItemAdded 事件触发时,您不再只是添加新项目,而是再次获取整个数据集。

    【讨论】:

    • 我今天一直在做一些研究,我在 Josh Smith 关于 WPF MVVM 的文章中发现了一些可以帮助我的东西。他说的是我可以以某种方式使用存储库来同步两个视图模型之间的数据。因此,当一个对象被添加到存储库时,存储库会触发一个事件,使视图模型刷新它们的可观察集合。我刚刚注意到这是你的第二个建议 xD 我认为这对我来说是最方便的:) 那么你能提供一些关于你的第二个建议的示例代码吗?
    • 第一个和第二个建议也不一样吗?有什么区别?
    • @user1757695 请参阅上面建议 2 的编辑。第一个与第二个不同,因为第二个需要再次从数据库中获取所有数据,而第二个只是将新项目转发到视图模型
    • 我现在明白其中的区别了:) 关于代码,您如何将相同的存储库实例传递给两个视图模型。由于我使用的是 MVVM Toolkit Light,这是 ViewModelLocator 的工作,我不确定它是否提供相同的参考。
    • 真的,您可能想看看使用 ioc 容器或 MEF - 我认为 mvvm light 包括 SimpleIOC,您应该能够在其中注册您的存储库。
    猜你喜欢
    • 1970-01-01
    • 2013-01-10
    • 2015-08-06
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多