如何将ObservableCollection与datagrid WPF绑定

时间:2016-05-06 11:36:12

标签: c# wpf xaml data-binding datagrid

我已经检查了这些链接,但没有解决我的问题。

我有两个模型类( Order.cs OrderItems.cs )和一个视图( Invoice.xaml

Order类中有 ObservableCollection(OrderItem),Invoice.xaml中有数据网格。我需要将ObservableCollection绑定到datagrid。 问题是,当项目被添加到ObservableCollection时,通过编写xaml代码进行绑定不会自动更新数据网格。

代码如下所示

订单类

public class Order
{
    public Order()
    {
        OrderItems =new ObservableCollection<OrderItem>();
    }

    public ObservableCollection<OrderItem> OrderItems { get; set; }

    public void GetOrderDetails(string customerId)
    {
        // method for getting set of OrderItmes objects and add to the 
        // ObservableCollection<OrderItem>
    }
}

OrderItem类

public class OrderItem
{
    public OrderItem(string supplierId, string itemId, string    itemName,decimal weight)
    {
        // some codes here
    }
    public string SupplierId { get; set; } // Supplier's ID
    public string ItemId { get; set; } // Item ID
    public string ItemName { get; set; }// Item Name
    public decimal Weight { get; set; } // weight of the item
}

Invoice.xaml的xaml代码(为简单起见,只显示必要的代码。 Model 是Order和OrderItem类的包。

    xmlns:model="clr-namespace:Onion.Model"
<Window.Resources>
    <model:Order x:Key="Order"/>
</Window.Resources>

<DataGrid x:Name="dataGrid" AutoGenerateColumns="False" CanUserResizeRows="False" Grid.ColumnSpan="8"
            Margin="0,0,30.5,0" CanUserResizeColumns="False" CanUserReorderColumns="False"
            CanUserSortColumns="False" CanUserAddRows="False" IsReadOnly="True"
            DataContext="{Binding Source={StaticResource Order}}" ItemsSource="{Binding OrderItems}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding SupplierId}" CanUserResize="False" FontSize="16"
                    Header="Supplier" Width="0.18*" />
                <DataGridTextColumn Binding="{Binding ItemId}" CanUserResize="False" FontSize="16"
                    Header="ItemID" Width="0.13*" />
                <DataGridTextColumn Binding="{Binding ItemName}" CanUserResize="False" FontSize="16"
                    Header="Item name" Width="0.2*" />
                <DataGridTextColumn Binding="{Binding Weight}" CanUserResize="False" FontSize="16" 
                    Header="Weight" Width="0.1*" />

 </DataGrid>

但是我可以通过在Invoice.xaml.cs类中编写必要的代码来编写xaml代码来实现这一点。

    private void txtBox_PreviewKeyDown(object sender, KeyEventArgs e){
    Order _order = new Order();
    _order.GetOrderDetails(customerId);// add OrderItems to the ObservableCollection

    // If this code is written some xaml codes are not needed (they are shown  below in the question
    dataGrid.ItemsSource = _order.OrderItems; // OrderItems is the ObservableCollection<OrderItem>  
}

(包括将每一列绑定到OrderItem中的属性)如果行dataGrid.ItemsSource = _order.OrderItems,则不需要以下代码;使用。

xmlns:model="clr-namespace:Onion.Model"
<Window.Resources>
    <model:Order x:Key="Order"/>
 </Window.Resources>
 DataContext="{Binding Source={StaticResource Order}}" ItemsSource="{Binding OrderItems}"

有人能指出我如何克服这个问题。

2 个答案:

答案 0 :(得分:1)

您的网格绑定到schema1静态资源:

Order

在您的事件处理程序中,您正在创建一个新的<Window.Resources> <model:Order x:Key="Order"/> </Window.Resources> <DataGrid DataContext="{Binding Source={StaticResource Order}}" ... 实例:

Order

然后,您正在调用一种方法,您可以将Order _order = new Order(); 添加到OrderItem中的OrderItems集合中。这您的_order绑定的OrderItems集合。

一个简单的修复可能是在后面的代码中声明你的DataGrid.ItemsSource并将其分配给构造函数中的Order

DataContext

然后从private readonly Order _order = new Order(); public WindowName() { DataContext = _order; } 中删除DataContext绑定(它将继承DataGrid)。然后,您可以从事件处理程序中删除Window.DataContext,然后使用实例字段Order _order = new Order()

理想情况下,您的事件处理程序不是必需的,_order中的ICommand将绑定到应添加新订单的任何按钮。

答案 1 :(得分:0)

填充数据时,您需要告诉框架数据已更新。

因此,从集合的Setter中的Viewmodel代码中,添加一行 RaisePropertyChanged(“ OrderItems”)是您告诉网格的绑定源名称。

此工作流程为:

  1. 在您的Xaml中,添加ItemsSource =“ {Binding Orders}”。这将是属性更改的名称,用于表示框架已发生某些更改。
  2. 在视图模型代码中,当您对集合进行更改时,将出现RaisePropertyChanged(“ Orders”)信号,该信号指示框架将数据封送至UI组件。
  3. 您的下一步将确定数据是从代码到UI还是从UI到代码,还是双向。因此,在您的xaml ItemSource =“ {Binding Orders,Mode = OneWay}中。当您在Visual Studio中时,它将弹出整个列表。在双向模式下,框架会将数据从UI编组到observablecollection。

对不起,我没有时间修改您的代码。希望这足以解释它。 干杯。