MVVM中的ObjectDataProvider没有必要吗?

时间:2010-06-30 16:04:08

标签: .net wpf mvvm objectdataprovider xamdatagrid

我创建了一个简单的MVVM,只有三个类CashFlowView,CashFlowViewModel,CashFlowModel。

我使用了infragistic的9.1 XamDataPresenter(或xamDataGrid)。

    <igDP:XamDataPresenter Name="xamDataPresenter1" DataSource="{Binding Source={StaticResource CashFlowData}}">

    <ObjectDataProvider x:Key="CashFlowData" ObjectType="{x:Type ViewModel:CashflowViewModel}" MethodName="GetCashFlows" />

在我的ViewModel中:

public ObservableCollection<CashflowModel> GetCashFlows()
        {
            return new ObservableCollection<CashflowModel>() { ... };
        }

ViewModel通过以下方式连接到View:

this.DataContext = new CashflowViewModel();

只要我将网格连接到ObjectDataProvider就可以完美运行。但我希望我可以直接连接到我的ViewModel中的属性。

根据Infragistics,我所要做的就是:

<igDP:XamDataGrid DataSource="{Binding Path=ViewModelCollection}"/>

但在这种情况下,我似乎需要绑定到另一个ViewModel的集合来表示网格内的行。那就是我感到困惑的地方。

我尝试了这个并且它不起作用:

<igDP:XamDataPresenter Name="xamDataPresenter1" DataSource="{Binding Path=CashFlows}">

在ViewModel中:

public ObservableCollection<CashflowDataGridViewModel> CashFlows
        {
            get
            {
                return new ObservableCollection<CashflowDataGridViewModel>();
            }
        }

但是如何创建我的第二个ViewModel(CashflowDataGridViewModel)?

我尝试在第二个ViewModel中添加此属性:

public CashflowModel CashFlow
        {
            get
            {
                return new CashflowModel() {...};
            }
        }

但是我在我的视图中显示的是“Cashflow”列标题,没有任何实际cashflowModel类的底层标题。

1 个答案:

答案 0 :(得分:1)

为了能够将View绑定到ViewModel上的属性,需要将DataContext设置为ViewModel的实例。我通常做的是在我的View的代码隐藏的构造函数中包含以下行:

this.DataContext = new SomeAwesomeViewModel();

如果希望不同的控件组使用不同的ViewModel(例如,Grid.DataContext,StackPanel.DataContext等),也可以为容器设置DataContext。

设置DataContext后,您应该能够绑定到该ViewModel的属性。

<强>更新

这里有一些示例代码可以帮助您。

public class CashFlowViewModel
{
    public ObservableCollection<FlowViewModel> DataGridData
    {
        get...
    }
}

这是应该为DataGrid提供数据的属性。现在,这是FlowViewModel类的样子。

public class FlowViewModel
{
    decimal flowAmount;
    public decimal FlowAmount
    {
        get { return flowAmount; }
        set
        {
            if(flowAmount == value)
                return;

            flowAmount = value;
            NotifyPropertyChanged("FlowAmount");
        }
    }
    .
    .
    .

    private void NotifyPropertyChanged(string propertyName)
    {
        if(PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}