WPF DataGrid – Dynamically updating DataGridComboBoxColumn

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.

ComboBoxSample1

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

ComboBoxSample2

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

ComboBoxSample3

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.

转载于:https://www.cnblogs.com/xpvincent/p/4256005.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值