MVVM 中的 ObjectDataProvider 没有必要吗?

发布于 2024-09-07 12:13:46 字数 1763 浏览 9 评论 0原文

我创建了一个简单的 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}">

Inside the ViewModel:

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

But how do I create my 第二个 ViewModel (CashflowDataGridViewModel) ?

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

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

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

I have created a simple MVVM, with only three classes CashFlowView, CashFlowViewModel, CashFlowModel.

I use an infragistic's 9.1 XamDataPresenter (or xamDataGrid).

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

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

Inside my ViewModel:

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

ViewModel is connected to View by this:

this.DataContext = new CashflowViewModel();

As long as I connect the grid to the ObjectDataProvider its perfectly running fine. But I wished I could just connect to a property within my ViewModel instead.

According to Infragistics all I have to do is this:

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

But in this case it seems I need to bind to a collection of another ViewModel to represent my rows inside the grid. And thats where I get confused.

I tried this and it doesnt work:

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

Inside the ViewModel:

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

But how do I create my second ViewModel (CashflowDataGridViewModel) ?

I tried adding this proprty within this second ViewModel:

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

But all I get shown on my view is "Cashflow" column header without any of the underlying headers of the actual cashflowModel class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

圈圈圆圆圈圈 2024-09-14 12:13:46

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

this.DataContext = new SomeAwesomeViewModel();

如果您希望不同的控件组使用不同的 ViewModel(例如 Grid.DataContext、StackPanel),您还可以为容器设置 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));
    }
}

To be able to bind the View to properties on the ViewModel, the DataContext needs to be set to an instance of your ViewModel. What I commonly do is to include the following line in the constructor of the code-behind for my View:

this.DataContext = new SomeAwesomeViewModel();

You can also set the DataContext for containers if you want different groups of controls to use different ViewModels (e.g., Grid.DataContext, StackPanel.DataContext, etc.).

Once you have the DataContext set, you should be able to bind to the properties of that ViewModel.

Update

Here's a bit of sample code to get you going.

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

That's the property which should provide the data for the DataGrid. Now, here's what the FlowViewModel class could look like.

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));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文