The Scenario

I want to do a master detail like scenario where the selection in one ComboBox cell will update the list of items in the next ComboBox cell and so on.

Setting up the DataSource and ViewModel

I will use the Northwind database for this example and will use the first column to select a Category within the Categories table.

The second column will have a ComboBox to select all the Products within the selected Category.

And the third column will have a ComboBox to select all the orders that were placed on the selected Product.

The ViewModel that I will use on each DataGrid item will have the properties:

· CurrentCategory

· CurrentProduct

· CurrentOrder

· ProductsInCategory

· OrdersFromProduct

Each time CurrentCategory is updated, ProductsInCategory will be updated as well to create the new list of products. When CurrentProduct is updated, OrdersFromProduct will be updated in a similar fashion. So for example, CurrentCategory will look like this:

public int CurrentCategory

{

get { return _currentCategory; }

set

{

_currentCategory = value;

ProductsInCategory =DBAccess.GetProductsInCategory(_currentCategory).Tables["Products"].DefaultView;

OnPropertyChanged("CurrentCategory");

}

}

GetProductsInCategory() does a query on the database passing in the category id. I will not go over the database querying implementation here.

Hooking up to the UI

For the first DataGridComboBoxColumn, the ComboBox.ItemsSource will bind to the Categories DataTable through a StaticResource. The binding on the column will be set to the CurrentCategory.

<dg:DataGridComboBoxColumn Header="Current Category"

SelectedValueBinding="{Binding Path=CurrentCategory}"

SelectedValuePath="CategoryID"

DisplayMemberPath="CategoryName"

ItemsSource="{Binding Source={StaticResourcecategoriesDataProvider}}">

</dg:DataGridComboBoxColumn>

The other DataGridComboBoxColumns will have to take a slightly different approach. Let’s say we do something like this:

<!--NOT CORRECT-->

<dg:DataGridComboBoxColumn Header="Current Product"

SelectedValueBinding="{Binding Path=CurrentProduct}"

SelectedValuePath="ProductID"

DisplayMemberPath="ProductName"

ItemsSource="{Binding Path=ProductsInCategory}">

</dg:DataGridComboBoxColumn>

It does seem more intuitive to take this approach however DataGridColumns are not actually part of the visual tree and only the Binding DPs will actually be set on generated cell elements to inherit DataGrid’s DataContext. That means that the binding for ItemsSource will fail as it won’t be able to find path, ProductsInCategory, that it is current set.

Aside: Jaime wrote this nice post on how to set the DataContext for the columns to DataGrid’s DataContext, but I’m going to show an implementation here with just the default implementation.

So what we want is for the ItemsSource to bind to the DataContext of the row on the DataGrid. We can do that by setting the binding on the actual generated element of the column through ElementStyle and EditingElementStyle.

<!—now itemssource will find the correct DataContext-->

<dg:DataGridComboBoxColumn Header="Current Product"

SelectedValueBinding="{Binding Path=CurrentProduct}"

SelectedValuePath="ProductID"

DisplayMemberPath="ProductName">

<dg:DataGridComboBoxColumn.ElementStyle>

<Style TargetType="ComboBox">

<Setter Property="ItemsSource" Value="{BindingPath=ProductsInCategory}" />

</Style>

</dg:DataGridComboBoxColumn.ElementStyle>

<dg:DataGridComboBoxColumn.EditingElementStyle>

<Style TargetType="ComboBox">

<Setter Property="ItemsSource" Value="{BindingPath=ProductsInCategory}" />

</Style>

</dg:DataGridComboBoxColumn.EditingElementStyle>

</dg:DataGridComboBoxColumn>

This works because internally when the cell is being generated, the Content of the cell will have its layout updated which will make it part of the visual tree and it will have access to the correct DataContext. Now the ItemsSource for the ComboBox will dynamically update each time CurrentCategory is changed. The DataGridComboBoxColumn for the CurrentOrder is similar to CurrentProduct so I will not show that here.

WPF DataGrid – Dynamically updating DataGridComboBoxColumn的更多相关文章

  1. 编写 WPF DataGrid 列模板,实现更好的用户体验

    Julie Lerman 下载代码示例 最近我在为一个客户做一些 Windows Presentation Foundation (WPF) 方面的工作. 虽然我提倡使用第三方工具,但有时也会避免使用 ...

  2. WPF DataGrid支持的列类型

    WPF DataGrid支持下面几种列类型: DataGridTextColumn DataGridCheckBoxColumn DataGridComboBoxColumn DataGridHype ...

  3. WPF DataGrid常用属性记录

    WPF DataGrid常用属性记录 组件常用方法: BeginEdit:使DataGrid进入编辑状态. CancelEdit:取消DataGrid的编辑状态. CollapseRowGroup:闭 ...

  4. WPF DATAGRID - COMMITTING CHANGES CELL-BY-CELL

    In my recent codeproject article on the DataGrid I described a number of techniques for handling the ...

  5. WPF DataGrid某列使用多绑定后该列排序失效,列上加入 SortMemberPath 设置即可.

    WPF DataGrid某列使用多绑定后该列排序失效 2011-07-14 10:59hdongq | 浏览 1031 次  悬赏:20 在wpf的datagrid中某一列使用了多绑定,但是该列排序失 ...

  6. xceed wpf datagrid

    <!--*********************************************************************************** Extended ...

  7. 获取wpf datagrid当前被编辑单元格的内容

    原文 获取wpf datagrid当前被编辑单元格的内容 确认修改单元个的值, 使用到datagrid的两个事件 开始编辑事件 BeginningEdit="dataGrid_Beginni ...

  8. WPF DataGrid绑定一个组合列

    WPF DataGrid绑定一个组合列 前台: <Page.Resources>        <local:InfoConverter x:Key="converter& ...

  9. WPF DataGrid自定义样式

    微软的WPF DataGrid中有很多的属性和样式,你可以调整,以寻找合适的(如果你是一名设计师).下面,找到我的小抄造型的网格.它不是100%全面,但它可以让你走得很远,有一些非常有用的技巧和陷阱. ...

随机推荐

  1. [网络流24题] 太空飞行计划(cogs 727)

    [问题描述] W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,-,Em},和进行这些实验需要使用的全部仪 ...

  2. NYOJ题目872开会

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsoAAAKwCAIAAAAOTc6wAAAgAElEQVR4nO3dO3LcSpOG4dkEfS6Edi

  3. JavaScript基础——处理字符串

    String对象是迄今为止在JavaScript中最常用的对象.在你定义一个字符串数据类型的变量的任何时候,JavaScript就自定为你创建一个String对象.例如: var myStr = &q ...

  4. javascript - 浏览器对象

    Navigator对象 弹出窗口 Cookies Browser Objects 参考手册 参考手册描述了每个对象的属性和方法,并提供了在线实例. Window 对象 Navigator 对象 Scr ...

  5. C#回顾 - 3.NET的IO:字节流

    使用 Stream 类管理字节流 使用 FileStream 类管理文件数据 使用 MemoryStream 类管理内存数据 使用 BufferedSream 类提高流性能   3.1 FileStr ...

  6. 在RedHat.Enterprise.Linux_v6.3系统中安装Oracle_11gR2教程

    在RedHat.Enterprise.Linux_v6.3系统中安装Oracle_11gR2教程 本教程提供PDF格式下载: 在RedHat.Enterprise.Linux_v6.3系统中安装Ora ...

  7. golang exec Command

    package mainimport ( "fmt" "log" "os/exec")func main() { out, err := e ...

  8. Entity Framework Code First for SQL Compact

    这篇博客将介绍EF Code First中如何使用SQL Compact.SQL Compact是微软推出的免费的关系型数据库,目前最新版本是SQL Compact 4.0.微软的开发工具VS 201 ...

  9. FP-Growth算法及演示程序

    FP-Growth算法 FP-Growth(频繁模式增长)算法是韩家炜老师在2000年提出的关联分析算法,它采取如下分治策略:将提供频繁项集的数据库压缩到一棵频繁模式树(FP-Tree),但仍保留项集 ...

  10. c中malloc的用法

    转自:http://blog.sina.com.cn/s/blog_966f8e8501010if7.html Malloc 向系统申请分配指定size个字节的内存空间.返回类型是 void* 类型. ...