【问题标题】:Mvvm: How to update my ObservableCollection<customobject> from another ViewModel?Mvvm:如何从另一个 ViewModel 更新我的 ObservableCollection<customobject>?
【发布时间】:2018-05-30 14:04:51
【问题描述】:

我很难理解如何更新 ViewModel2 中的 ObservableCollection,它是在 ViewModel1 中定义的。我已经搜索了很多关于如何做到这一点,但无法得到正确的理解。我正在使用 MVVM Light 框架。

我有一个 DozentViewModel,它有一个 ObservableCollection 的 Dozents。 我有另一个 AddDozentViewModel 用于通过实体框架将新的 Dozent 添加到数据库中。但是如何将新的 Dozent 添加到 DozentViewModel 中的 ObservableCollection 中?

这是我的 DozentViewModel:

public class DozentViewModel : ViewModelBase
{
    private IDozentDB _dozentDB;
    private ObservableCollection<Dozent> _dozentList;
    private string _nachName;
    private string _vorName;
    private string _akadGrad;

    public RelayCommand ShowAddDozentCommand { get; private set; }

    public ObservableCollection<Dozent> DozentList
    {
        get { return _dozentList; }
        set
        {
            Set(ref _dozentList, value);
            RaisePropertyChanged("DozentList");
        }

    }

    public DozentViewModel(IDozentDB dozentDB)
    {

        _dozentDB = dozentDB;
        DozentList = new ObservableCollection<Dozent>();

        // To get list of all Dozents  
        DozentList = _dozentDB.GetAllDozents();

        ShowAddDozentCommand = new RelayCommand(ShowAddDozentViewExecute);

    }

我已将 DozentList 属性绑定到我的 DozentView :

&lt;DataGrid ItemsSource="{Binding DozentList,UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" CanUserAddRows="False" IsReadOnly="True" Grid.Column="0" &gt;

这是我的 AddDozentViewModel,它将新的 Dozent 添加到我的 SQL 数据库中。

public AddDozentViewModel(IDozentDB dozentDB)
    {
        _dozentDB = dozentDB;

        // To Add Dozent details to Dozent DB 
        AddCommand = new RelayCommand(AddDozent, CanAddDozent);

     }
    public string NachName
    {
        get { return _nachName; }
        set
        {
            Set(ref _nachName, value);
            RaisePropertyChanged("NachName");
            AddCommand.RaiseCanExecuteChanged();
        }
    }

    public string VorName
    {
        get { return _vorName; }
        set
        {
            Set(ref _vorName, value);
            RaisePropertyChanged("VorName");
            AddCommand.RaiseCanExecuteChanged();
        }
    }

    public string AkadGrad
    {
        get { return _akadGrad; }
        set
        {
            Set(ref _akadGrad, value);
            RaisePropertyChanged("AkadGrad");
            AddCommand.RaiseCanExecuteChanged();

        }
    }
    private void AddDozent()
    {
        Dozent dozent = new Dozent();
        dozent.DozentNachname = this.NachName;
        dozent.DozentVorname = this.VorName;
        dozent.AkadGrad = this.AkadGrad;

        _dozentDB.Create(dozent);



        Messenger.Default.Send(new NotificationMessage("CloseAddDozentView"));
    }

    private bool CanAddDozent()
    {
        return (!string.IsNullOrEmpty(NachName)) && (!string.IsNullOrEmpty(VorName)) && (!string.IsNullOrEmpty(AkadGrad));
    }

}

我知道我只是将新的 Dozent 添加到数据库中,而不是更新 ObservableCollection。因此我在 DozentView 上的 DataGridView 没有得到更新。我该怎么做呢?任何信息都会非常有帮助!

谢谢, 维尼塔

【问题讨论】:

    标签: wpf mvvm mvvm-light observablecollection


    【解决方案1】:

    我希望在这里做的事情类似于使AddDozentViewModel 成为DozentViewModel 的属性,其中将包含对其父级的引用,例如:

    public class AddDozentViewModel
    {
        private readonly DozentViewModel _parent;
    
        ...
    
        public AddDozentViewModel(DozentViewModel parent, IDozentDB dozentDB)
        {
            _parent = parent;
            _dozentDB = dozentDB;
        }
    
        ...
    
        private void AddDozent()
        {
            Dozent dozent = new Dozent();
            dozent.DozentNachname = this.NachName;
            dozent.DozentVorname = this.VorName;
            dozent.AkadGrad = this.AkadGrad;
    
            _dozentDB.Create(dozent);
    
            _parent.DozentList.Add(dozent);
    
            Messenger.Default.Send(new NotificationMessage("CloseAddDozentView"));
    
            _parent.AddDozentViewModel = null; // this will dispose of the AddDozentViewModel
        }
    
        ...
    }
    

    DozentViewModel 因此看起来像这样:

    public class DozentViewModel : ViewModelBase
    {
        ...
    
        private AddDozentViewModel _addDozentViewModel;
        public AddDozentViewModel AddDozentViewModel
        {
            get { return _addDozentViewModel; }
            set
            {
                Set(ref _addDozentViewModel, value);
                RaisePropertyChanged("_addDozentViewModel");
            }
        }
    
        ...
    }
    

    另外,为了更加确定新的Dozent 已写入数据库,所以我总觉得我与数据库同步,我可能会考虑从数据库中检索新的Dozent在将其添加到 DozentList 之前。所以这会将AddDozent() 方法更改为:

    private void AddDozent()
    {
        Dozent dozent = new Dozent();
        dozent.DozentNachname = this.NachName;
        dozent.DozentVorname = this.VorName;
        dozent.AkadGrad = this.AkadGrad;
    
        _dozentDB.Create(dozent);
    
        Dozent newDozentFromDB = // retrieve it from _dozentDB here
    
        _parent.DozentList.Add(newDozentFromDB);
    
        Messenger.Default.Send(new NotificationMessage("CloseAddDozentView"));
    
        _parent.AddDozentViewModel = null; // this will dispose of the AddDozentViewModel
    }
    

    【讨论】:

    • 非常感谢您的澄清。
    • 成功了!! :) 我有一个微不足道的疑问。我喜欢从数据库中检索新添加的 Dozent 并将其添加到我的 ObservableCollection 的想法。这样做,我正在用它的 Id 来检索它,就像这样:Dozent newDozentFromDB = _dozentDB.GetDozent(dozent.DozentId);。我希望我用正确的打结 ID 检索打结?无论如何,它可以工作,我可以在数据网格中查看更新的集合。
    • 是的,我不太确定您是如何使用数据库的,所以我没有详细说明,但任何识别您独特的Dozent 的方法都可以。您甚至可以将其重构为一个接受 Dozent 的方法,将其添加到数据库中,然后返回 Dozent 供您添加到集合中。
    【解决方案2】:

    您可以使用 MVVMLight 的Messenger 进行视图模型通信。

    例如:

    public class AddDozentViewModel
    {
        //... 
    
        private void AddDozent()
        {
            Dozent dozent = new Dozent();
            //...
    
            Messenger.Default.Send(new NewDozentAddedMessage(dozent));
        }
    }
    
    public class DozentViewModel
    {
        //...
    
        private ObservableCollection<Dozent> _dozentList;
        public DozentViewModel()
        {
            Messenger.Default.Register<NewDozentAddedMessage>(this, HandleNewDozentAddedMessage);
        }
        private void HandleNewDozentAddedMessage(NewDozentAddedMessage obj)
        {
            _dozentList.Add(obj.DozentObject);
        }
    }
    
    public class NewDozentAddedMessage
    {
        public Dozent DozentObject { get; }
        public NewDozentAddedMessage(Dozent dozentObject)
        {
            DozentObject = dozentObject;
        }
    }
    

    【讨论】:

    • 非常感谢您提供这些信息!真的很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 2017-01-04
    • 1970-01-01
    • 2020-11-25
    • 2017-05-24
    相关资源
    最近更新 更多