如何在WPF / MVVC C#中实现动态绑定

时间:2017-11-02 15:48:03

标签: c# .net wpf

我对MVVC / wpf很新,主要使用winforms。

我想要实现的是动态数据绑定,而不使用WPF中的代码。用户界面由一个devexpress网格和几个按钮组成。每个按钮按下加载对象列表并在网格中显示对象。列表包含不同的对象类型,具体取决于按下的按钮。在这个例子中,我有两个类:FatCat和FatDog。

在winforms中有效:

    private void button1_Click(object sender, EventArgs e)
    {
        ((GridView)gridCtrl.MainView).Columns.Clear();
        gridCtrl.DataSource = new BindingSource(itsModel.GetAll<FatDog>(), null);
    }


    private void button2_Click(object sender, EventArgs e)
    {
        ((GridView)gridCtrl.MainView).Columns.Clear();
        gridCtrl.DataSource = new BindingSource(itsModel.GetAll<FatCat>(), null);
    }

我已经将网格配置为动态创建列,所以一切正常。 itsModel的类型为CatClientModel。

在wpf中,我已将DataContext定义为CatClientModel。

我应该在网格中使用ItemsSource来实现与winforms解决方案相同的行为?

dxg:GridControl ItemsSource =“{Binding SomeDynamicList}”

换句话说,SomeDynamicList在上面的代码中应该是什么?或者我是以错误的方式解决这个问题?

正如我所说,我使用DevExpress wpf网格控件,但问题应该是通用的,并且适用于任何控件呈现对象列表。

2 个答案:

答案 0 :(得分:1)

  

换句话说,上面代码中SomeDynamicList应该是什么?

SomeDynamicList应该是ObservableCollection<T>属性,您可以在其中添加要在T中显示的GridControl类型的任何对象。

DataContext或其任何父元素的GridControl设置为定义此属性的类的实例:

public class CatClientModel
{
    public ObservableCollection<Animal> SomeDynamicList { get; } = new ObservableCollection<Animal>();
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new CatClientModel();
    }
}
  

确定。但问题是ObservableCollection包含不同的类型。遗憾的是,没有可行的继承类。我想绑定到ObservableCollection或ObservableCollection,具体取决于按下的按钮

然后切换DataContext,或者将属性更改为IEnumerable,并在每次单击按钮时将其设置为新的集合。这要求您在视图模型中实现INotifyPropertyChanged接口

private System.Collections.IEnumerable _collection;
public System.Collections.IEnumerable MyProperty
{
    get { return _collection; }
    set { _collection = value; OnPropertyChanged(); }
}

答案 1 :(得分:1)

如果要使用XAML定义代码映射到哪个数据源,请为每个可能的网格。这确实需要MVVM管理器的至少一些方法,使用prism或mvvmlight将视图模型连接到视图。

所以如果你去了MVVM模型路线,模型会包含你的每个网格的描述:

 public BulkObservableCollection<icd10facet> FacetList
    {
        get { return this._facets; }
        set { SetProperty(ref this._facets, value); }

    }
    public INotifyTaskCompletion<BulkObservableCollection<PetsConvert>> ConceptList
    {
        get { return this._concept; }
        set
        {
            SetProperty(ref this._concept, value);
        }
    }

在代码的XAML中,网格woud以这种方式绑定到ConceptList定义的网格:

ItemsSource="{Binding ConceptList.Result}" 

这个答案并没有解决如何连接Prism 6.0以使用视图模型的例子,但是例子见:

https://github.com/PrismLibrary/Prism

其中包含文档和入门代码。请记住,没有任何特定的理由将代码置于视图后面的代码中是一个问题,首先解决问题,然后重构,如果关注点分离是一个问题。

使用此技术,您可以将每个网格绑定到自己的数据源。在MVVM空间按钮和其他东西中使用命令模型与视图模型进行通信。

 <Button Content="Load Rule Data" Width="100" Height="40" HorizontalAlignment="Left" Margin="5px" Command="{Binding LoadRuleData }"/>

这需要在viewmodel中为LoadRuleData

定义命令委托
    public DelegateCommand LoadRuleData { get; private set; }

然后(通常在构造函数中)将DelegateCommand连接到将要完成工作的方法。

 this.LoadRuleData = new DelegateCommand(this.loadRules);