MVVM命令绑定

时间:2009-12-05 12:27:03

标签: c# wpf mvvm commandbinding

我正在尝试学习MVVM模式。我遇到的主要问题是学习我应该声明的位置,创建和绑定命令对象。

2个例子:

  1. 我有一个主要表单,就像一个开关板或主菜单。显示选择按钮1和视图1,选择按钮2,显示视图2。大。现在我想回到主窗体,所以我需要一个名为“主菜单”的视图1(和视图2)上的按钮。我应该在哪里定义命令和命令处理程序,以便我可以绑定到“ShowMainMenu”命令?我可以在View2ViewModel中创建它们但是我没有权限显示主视图?或者,我可以在MainView模型中创建thim但是然后如何在子视图模型中绑定它们(我根据mvvm建议使用RelayCommand obejct并且它们不会冒泡到父级。)

  2. 我在一个主窗口视图中可以看到两个用户控件,我们称之为MainView,UC1和UC2。每个都有ViewModel MainViewModel,UC1ViewModel,UC2View Model。我在UC1上有一个名为“AddItem”的按钮。它应该在UC2的列表中添加一个项目。 设置“AddItemCommand”并绑定到它的当前方法是什么。 Command应该在MainViewModel,Uc1ViewModel还是UC2ViewModel?我怎么会和它结合起来。

  3. 感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

1)您可以从一个基本ViewModel继承View1Model和View2Model,并在那里定义ShowMainMenu。

或(这是我的方法)

使用ContentPresenter创建RootView,它将显示您的所有视图。使用ViewContent属性创建RootVeiwModel。将ContetnPresenter的内容属性绑定到RootViewModel的ViewContent属性。您可以使用object作为ViewContent的类型,但我建议您定义MainVView1Model,View1Model和View2Model支持的接口。更改ViewContent必须引发ProprtyChangedEvent。 在RootViewModel中定义ShowMainViewCommand,它只会将ViewContent更改为MainViewModel(它将显示为MainView)。然后将View1和View2中Button的Command属性绑定到该命令,例如:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RootView}}, 
                         Path=DataContext.ShowMainViwe}

有一些代码可以解释我想说的内容:

RootView.xaml

...
<ContentPresenter Content={Binding ViewContent} />
...

RootViewModel.ca

class RootViewModel : INotifyPropertyCahnged
{
    ...
    private object _ViewContent;
    public object ViewContent
    {
        get {return _ViewContent;}
        set
        {
            _ViewContent = value;
            if (PropertyChanged != null)
            {
                PropertyChanged ("ViewContent");
            }

        }
    }

    private RelayCommand _ShowMainView;
    public ICommand ShowMainView
    {
        get 
        {
            if (_ShowMainView == null)
            {
                _ShowMainView = new RelayCommand(x => ViewContent = new MainViewModel());
            }
            return _ShowMainView;
        }
    }
    ...
}

2)将对MainViewModel的引用添加到UC1ViewModel和UC2ViewModel - 这就是影响其他控件的方式。 MainViwModel必须包含包含UC1ViewModel和UC2ViewModel的属性第二个用户控件的项必须包含在ObservableCollection中。

我只是通过代码向您展示它是如何工作的:

class UC1ViewModel : INotifyPropertyChanged
{
    ...
    private MainViewModel _Parent;
    public UC1ViewModel(MainViewModel parent)
    {
        _Panert = parent;
    }

    private RelayCommand _AddItemToUC2;
    public ICommand AddItemToUC2
    {
        get
        {
            if (_AddItemToUC2 = null)
            {
                // UC2Content is UC2ViewModel
                // Items is ObservableCollection
               _AddItemToUC2 = new RelayCommand(x => _Parent.UC2Content.Items.Add(...));
            }
            return AddItemToUC2;
        }
    }
    ...
}

答案 1 :(得分:2)

MainModel可以为每个UCxViewModel提供一个属性,或者更简单的是ViewModel列表。 “Show”命令将创建相应的UVxViewModel,订阅由UVxViewModel发布的“OnClose”事件,并将其添加到列表中。 MainView具有绑定到此列表的控件(例如Tab控件)和定义要用于每个UCxViewModel的视图的DataTemplates。 当UVxViewModel触发其OnClose事件时,MainModel将其从列表中删除,从而导致相应的视图“关闭”。

对于“添加项目”部分,ViewModel应共享相同的项目列表(模型)。然后UC2ViewModel可以添加一个项目,UC1View会更新(如果列表实现了INotifyCollectionChanged)。

我发现this explanation对理解MVVM很有帮助。