Mvvm:如何更新我的ObservableCollection 从另一个ViewModel?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mvvm:如何更新我的ObservableCollection 从另一个ViewModel?相关的知识,希望对你有一定的参考价值。

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

我有一个DozentViewModel,它有一个ObzeableCollection的Dozents。我有另一个AddDozentViewModel,用于通过Entity Framework将新的Dozent添加到数据库。但是如何在DozentViewModel中将新的Dozent添加到我的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:

<DataGrid ItemsSource="{Binding DozentList,UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" CanUserAddRows="False" IsReadOnly="True" Grid.Column="0" >

这是我的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没有得到更新。我该怎么做呢?任何信息都会非常有用!!

Dongz,Winita

答案

我在这里要做的是使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
}
另一答案

您可以使用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;
    }
}

以上是关于Mvvm:如何更新我的ObservableCollection 从另一个ViewModel?的主要内容,如果未能解决你的问题,请参考以下文章

WPF MVVM:如何根据事件更新 UI 控制器

如何在listview - WPF MVVM上拖放后更新codeBehind中的ObservableCollection

按钮内容不更新 [MVVM]

如何在 MVVM-WPF 中获取所选项目

来自事件处理程序的 ReactiveUI MVVM 更新属性

MVVM:修改模型,如何正确更新 ViewModel 和 View?