【问题标题】:Adding databing to a datagrid?向数据网格添加数据?
【发布时间】:2013-07-02 13:46:36
【问题描述】:

我有一个简单的数据结构如下:

在我的模型中

    public class Receipt
    {
    public int Id { get; set; }
    public double Price { get; set; }
    public string Store { get; set; }
    public DateTime Date { get; set; }
    }

我已经制作了两个这样的对象,我正在尝试将它们绑定到数据网格。我已经填写了两张收据的属性并将它们添加到 dataGridRows,但它们没有显示在我的 DataGrid 中。

    public MainWindow()
    {
    InitializeComponent();
    makeReceipts()
    }

    public ObservableCollection<Receipt> dataGridRows = new ObservableCollection<Receipt>();

    public Receipt receipt1 = new Receipt();
    public Receipt receipt2 = new Receipt();

    public void makeReceipts()
    {
    receipt1.Id = 1;
    receipt1.Price = 10;
    receipt1.Store = "Brugsen";
    receipt1.Date = DateTime.Today;

    receipt2.Id = 2;
    receipt2.Price = 15;
    receipt2.Store = "Netto";
    receipt2.Date = DateTime.Today;

    dataGridRows.Add(receipt1);
    dataGridRows.Add(receipt2);
    }

在我希望我的数据网格显示我拥有的收据的 MainWindow 的 xaml 中:

    <DataGrid Name="ReceiptGrid" CanUserResizeColumns="True" IsReadOnly="True" AutoGenerateColumns="True" ItemsSource="{Binding Source=dataGridRows}" />

我做错了什么?

【问题讨论】:

  • 这个public ObservableCollection&lt;Receipt&gt; dataGridRows是在哪里定义的?
  • 在 MainWindow.xaml.cs 中,就在我用来声明两个对象属性的方法之外..

标签: wpf object data-binding binding datagrid


【解决方案1】:

首先您可以绑定到公共属性。 所以如果你想使用绑定,你至少要做:

 public ObservableCollection<Receipt> dataGridRows {get;set;}

其次你必须做两个步骤:

  1. 设置正确的数据上下文
  2. 设置正确的绑定表达式(路径)

假设你的网格的数据上下文是一个具有 dataGridRows 属性的对象,你的绑定应该是这样的

 <DataGrid ItemsSource="{Binding Path=dataGridRows}" .../>

【讨论】:

    【解决方案2】:

    认为你的问题是你必须写

    ItemsSource="{Binding Path=dataGridRows}"
    

    而不是

    ItemsSource="{Binding Source=dataGridRows}"
    

    source是在xaml文件中指定另一个控件

    【讨论】:

      【解决方案3】:

      首先,您只能绑定公共属性,因此您需要将 dataGridRows 的定义更改为如下内容:

      public ObservableCollection<Receipt> dataGridRows { get; set; }
      

      那么你不会将它绑定为Source,而是绑定为Path,但是由于你的dataGridRows 是在MainWindow 中定义的,你需要将Source 指定为MainWindow,否则它看起来默认为DataContext,在您的情况下未设置

      <DataGrid ... ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=dataGridRows}" />
      

      这告诉Binding 找到Window 并在那里寻找dataGridRows 属性。

      编辑:
      通常您不会将数据放入视图中.我建议您阅读有关 MVVM 设计模式的更多信息,但基本上这个想法是您拥有 ViewModel,您将整个应用程序逻辑放入其中,不知道界面,然后在顶部您有与用户交互的视图,但在 ViewModel 中您没有t 对控件进行操作。
      您应该做的是使用 dataGridRows 属性创建视图模型类,并通过 WindowDataContext 分配它。每个FrameworkElement 都有它,当您不指定Binging 源(SourceRelativeSourceElementName)时,它将尝试在当前DataContext 中解析Binding.Path。如果当前控件没有指定,则 if 将转到可视树中的父级,依此类推。

      【讨论】:

      • 如果我的 dataGridRows 放在其他地方,什么位置比较好?我应该在 Receipt 模型本身中定义它吗?
      • @Zeliax,我已经更新了我的答案,简要说明了你应该做什么
      • 谢谢。这让它变得更容易理解了。所以基本上我应该创建一些控件(ViewModel 中的类)来处理所有模型。一个示例可能是 ReceiptViewModel,它创建收据实例并处理数据? AddReceipt 和类似的东西应该在 ReceiptViewModel 中还是怎么样?
      • @Zeliax:是的,这正是它应该如何工作的。基本上 ViewModel 是独立于 UI 的应用程序,它使用模型中的通用类(如 DB 访问),并且 View 绑定到它以允许交互。如果您只是从 WPF 开始,那么从 MVVM 开始将是最容易的。有现成的框架,如MVVM Light,这使它更容易。在 WPF 中,您只需与控件进行很少的交互,UI 基本上是通过模板和绑定创建自己的。
      • 感谢您的回复。我目前正在努力提高我的 MVVM 编码技能,这似乎有点棘手,但幸运的是,互联网上的 MVVM 教程比简单的数据绑定要好得多;)
      猜你喜欢
      • 2015-10-07
      • 2013-12-21
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      相关资源
      最近更新 更多