如何将 ObservableCollection 与 datagrid WPF 绑定
Posted
技术标签:
【中文标题】如何将 ObservableCollection 与 datagrid WPF 绑定【英文标题】:How to bind ObservableCollection with datagrid WPF 【发布时间】:2016-09-01 11:15:38 【问题描述】:我已经检查了这些链接,但没有解决我的问题。
How to bind WPF DataGrid to ObservableCollection
Bind an ObservableCollection to a wpf datagrid : Grid stays empty
我有两个模型类(Order.cs 和 OrderItems.cs)和一个 View(Invoice.xaml)
Order 类中有 ObservableCollection(OrderItem),Invoice.xaml 中有一个数据网格。我需要将 ObservableCollection 绑定到数据网格。 问题是,当项目添加到 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"
谁能告诉我如何克服这个问题。
【问题讨论】:
您绑定到的Order
与您在事件处理程序中修改的不是同一个。
您如何将 OrderItem 添加到您的订单中?
@Nitin 通过 GetOrderDetails(string customerId) 方法将 OrderItems 添加到 ObservableCollection您的网格绑定到Order
静态资源:
<Window.Resources>
<model:Order x:Key="Order"/>
</Window.Resources>
<DataGrid DataContext="Binding Source=StaticResource Order" ...
在您的事件处理程序中,您正在创建一个新的 Order
实例:
Order _order = new Order();
然后您调用一个方法,您说,该方法将OrderItem
添加到_order
中的OrderItems
集合中。这不是您的DataGrid.ItemsSource
绑定到的OrderItems
集合。
一个简单的解决方法可能是在后面的代码中声明您的Order
,并将其分配给构造函数中的DataContext
:
private readonly Order _order = new Order();
public WindowName()
DataContext = _order;
然后从DataGrid
中删除DataContext
绑定(它将继承Window.DataContext
)。然后,您可以从事件处理程序中删除 Order _order = new Order()
并改用实例字段 _order
。
理想情况下,不需要您的事件处理程序,并且您的Order
中会有一个ICommand
,它将绑定到应该添加新订单的任何按钮。
【讨论】:
【参考方案2】:当您填充数据时,您需要告诉框架数据已更新。
因此,从集合的 Setter 中的 Viewmodel 代码中,添加一行内容 RaisePropertyChanged("OrderItems") 这是您告诉网格的绑定源名称。
这个工作流程是:
-
在您的 Xaml 中添加 ItemsSource="Binding Orders"。这将是 propertychanged 的名称,用于向框架发出信号已更改。
在您的视图模型代码中,当您对集合进行更改时,您将发出 RaisePropertyChanged("Orders") 信号,通知框架将数据编组到 UI 组件。
下一步将确定数据是从代码流向 UI,还是从 UI 流向代码,或者双向。因此,在您的 xaml ItemSource="Binding Orders, Mode=OneWay 中。当您在 Visual Studio 中时,它会弹出整个列表。在双向模式下,框架会将您的数据从 UI 编组到 observablecollection。
抱歉,我没有时间修改您的代码。希望这能很好地解释它。 干杯。
【讨论】:
以上是关于如何将 ObservableCollection 与 datagrid WPF 绑定的主要内容,如果未能解决你的问题,请参考以下文章
如何将 WPF DataGrid 绑定到 ObservableCollection
如何将 ObservableCollection 与 datagrid WPF 绑定
将 ObservableCollection 保存到文件 (.txt)
C#如何将实体框架实体与ObservableCollection一起使用