绑定DataGridComboBoxColumn中的相关数据
Binding Related Data in DataGridComboBoxColumn
我有一个数据网格可以很好地显示数据,但现在我想用它来编辑数据。如何配置 DataGridComboBoxColumn
显示描述,但绑定到相关 table 的 ID?
我的数据通过 EF 进入应用程序,但为了将正确过滤的数据输入 DataGrid
,我使用 DbQuery
创建一个 List<>
,然后将其设置为DataGrid
的 ItemsSource
:
private void OnControlLoaded(object sender, RoutedEventArgs e)
{
DbQuery<Product> whiteGoodsProductQuery = this.GetWhitegoodsProductsQuery(myEntities);
List<Product> lstWhiteGoodsProducts = whiteGoodsProductQuery.ToList<Product>();
dgridWhitegoodProducts.ItemsSource = lstWhiteGoodsProducts;
}
这样填充 DataGrid
:
<DataGrid x:Name="dgridWhitegoodProducts" AutoGenerateColumns="False">
<DataGrid.Columns>
<!-- Manufacturer -->
<DataGridTextColumn Header="Manufacturer" Binding="{Binding Manufacturer.CompanyName}" />
<!-- Product -->
<DataGridTextColumn Header="Name" Binding="{Binding ProductName }" />
<!-- Description -->
<DataGridTextColumn Header="Product Description" Binding="{Binding ProductDescription }"/>
<!-- Length -->
<DataGridTextColumn Header="Length (mm)" Binding="{Binding Length}"/>
<!-- Width -->
<DataGridTextColumn Header="Width (mm)" Binding="{Binding Width}"/>
<!-- Height -->
<DataGridTextColumn Header="Height (mm)" Binding="{Binding Height}"/>
<!-- Price -->
<DataGridTextColumn Header="Price" Binding="{Binding UnitPrice}"/>
</DataGrid.Columns>
</DataGrid>
现在,我想将制造商 DataGridTextColumn
更改为 DataGridComboBoxColumn
,以便用户可以 select 其他制造商。当我设置 ComboBox 列时,我没有得到任何数据,所以我显然在绑定中做错了。
这是我的组合框列最初的样子:
<DataGridComboBoxColumn Header="Manufacturer"
SelectedValueBinding="{Binding ManufacturerID, Mode=TwoWay}"
SelectedValuePath="Manufacturer.ID"
DisplayMemberPath="Manufacturer.CompanyName" />
目前看起来像:
<DataGridComboBoxColumn Header="Manufacturer" SelectedValueBinding="{Binding
ManufacturerID}" SelectedValuePath="ID" DisplayMemberPath="CompanyName}"
ItemsSource="{Binding Source={StaticResource ManufacturerList}" />
ItemsSource 来自代码隐藏中的静态 ObservableCollection。
public static ObservableCollection<Manufacturer> ManufacturerList = new
ObservableCollection<Manufacturer>(new MyEntities().Manufacturers);
我在 SelectedValuePath、SelectedValueBinding 等属性中尝试了 [TableName.]Field 的多种变体,但无济于事。
接下来我尝试的是在 ComboBoxColumn 可以绑定到的代码隐藏中创建一个列表 List,但是当我将 List 设置为 ItemsSource 时,我得到:System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ManufacturerList; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=14427695); target property is 'ItemsSource' (type 'IEnumerable')
.
将该 List 更改为 ObservableCollection 也不起作用,也没有将其设为静态。
谁能看出我做错了什么以及我应该从这里走哪条路?
您必须像下面这样定义用户控制资源
<UserControl.Resources>
<CollectionViewSource x:Key="UserTypeList" Source="{Binding DomainUserTypes}" /> </UserControl.Resources>
如下绑定数据网格组合列
DataGridComboBoxColumn Header="User Type"
ItemsSource="{绑定源={StaticResource UserTypeList}}
DomainType 将是视图模型 属性。
DomainUserTypes = new ObservableCollection();
只需用数据填充视图模型 属性 并进行测试,它就会起作用。
您只能绑定到 public properties 并且 ManufacturerList
是一个字段。
如果您在 UserControl
的代码隐藏中将其定义为非静态 属性:
public ObservableCollection<Manufacturer> ManufacturerList { get; } = new ObservableCollection<Manufacturer>(new MyEntities().Manufacturers);
...你可以这样绑定它:
<DataGridComboBoxColumn Header="Manufacturer" SelectedValueBinding="{Binding ManufacturerID, Mode=TwoWay}"
SelectedValuePath="ID"
DisplayMemberPath="CompanyName">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.ManufacturerList, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.ManufacturerList, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
ID
和 CompanyName
应该是 Manufacturer
的 public 属性 class 和 ManufacturerID
是 public 属性 Product
class.
您需要在样式中设置 ItemsSource
属性 的原因是 DataGridComboBoxColumn
不是添加到元素树中的可视元素,因此它具有没有视觉祖先。
编辑:
So apparently the DataContext
of your UserControl
is a CollectionViewSource
. This is an example of why you should always provide a reproducible sample of your issue when asking a question.
无论如何,你可以在你的 UserControl
中定义另一个 CollectionViewSource
并将这个的 Source 设置为你的 Manufacturer
对象集合并像这样绑定列:
<DataGridComboBoxColumn ... ItemsSource="{Binding Source={StaticResource ManufacturerList}}" />
...其中 ManufacturerList
是 CollectionViewSource
的 x:Key
。
我有一个数据网格可以很好地显示数据,但现在我想用它来编辑数据。如何配置 DataGridComboBoxColumn
显示描述,但绑定到相关 table 的 ID?
我的数据通过 EF 进入应用程序,但为了将正确过滤的数据输入 DataGrid
,我使用 DbQuery
创建一个 List<>
,然后将其设置为DataGrid
的 ItemsSource
:
private void OnControlLoaded(object sender, RoutedEventArgs e)
{
DbQuery<Product> whiteGoodsProductQuery = this.GetWhitegoodsProductsQuery(myEntities);
List<Product> lstWhiteGoodsProducts = whiteGoodsProductQuery.ToList<Product>();
dgridWhitegoodProducts.ItemsSource = lstWhiteGoodsProducts;
}
这样填充 DataGrid
:
<DataGrid x:Name="dgridWhitegoodProducts" AutoGenerateColumns="False">
<DataGrid.Columns>
<!-- Manufacturer -->
<DataGridTextColumn Header="Manufacturer" Binding="{Binding Manufacturer.CompanyName}" />
<!-- Product -->
<DataGridTextColumn Header="Name" Binding="{Binding ProductName }" />
<!-- Description -->
<DataGridTextColumn Header="Product Description" Binding="{Binding ProductDescription }"/>
<!-- Length -->
<DataGridTextColumn Header="Length (mm)" Binding="{Binding Length}"/>
<!-- Width -->
<DataGridTextColumn Header="Width (mm)" Binding="{Binding Width}"/>
<!-- Height -->
<DataGridTextColumn Header="Height (mm)" Binding="{Binding Height}"/>
<!-- Price -->
<DataGridTextColumn Header="Price" Binding="{Binding UnitPrice}"/>
</DataGrid.Columns>
</DataGrid>
现在,我想将制造商 DataGridTextColumn
更改为 DataGridComboBoxColumn
,以便用户可以 select 其他制造商。当我设置 ComboBox 列时,我没有得到任何数据,所以我显然在绑定中做错了。
这是我的组合框列最初的样子:
<DataGridComboBoxColumn Header="Manufacturer"
SelectedValueBinding="{Binding ManufacturerID, Mode=TwoWay}"
SelectedValuePath="Manufacturer.ID"
DisplayMemberPath="Manufacturer.CompanyName" />
目前看起来像:
<DataGridComboBoxColumn Header="Manufacturer" SelectedValueBinding="{Binding
ManufacturerID}" SelectedValuePath="ID" DisplayMemberPath="CompanyName}"
ItemsSource="{Binding Source={StaticResource ManufacturerList}" />
ItemsSource 来自代码隐藏中的静态 ObservableCollection。
public static ObservableCollection<Manufacturer> ManufacturerList = new
ObservableCollection<Manufacturer>(new MyEntities().Manufacturers);
我在 SelectedValuePath、SelectedValueBinding 等属性中尝试了 [TableName.]Field 的多种变体,但无济于事。
接下来我尝试的是在 ComboBoxColumn 可以绑定到的代码隐藏中创建一个列表 List,但是当我将 List 设置为 ItemsSource 时,我得到:System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ManufacturerList; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=14427695); target property is 'ItemsSource' (type 'IEnumerable')
.
将该 List 更改为 ObservableCollection 也不起作用,也没有将其设为静态。
谁能看出我做错了什么以及我应该从这里走哪条路?
您必须像下面这样定义用户控制资源
<UserControl.Resources>
<CollectionViewSource x:Key="UserTypeList" Source="{Binding DomainUserTypes}" /> </UserControl.Resources>
如下绑定数据网格组合列
DataGridComboBoxColumn Header="User Type" ItemsSource="{绑定源={StaticResource UserTypeList}}
DomainType 将是视图模型 属性。
DomainUserTypes = new ObservableCollection();
只需用数据填充视图模型 属性 并进行测试,它就会起作用。
您只能绑定到 public properties 并且 ManufacturerList
是一个字段。
如果您在 UserControl
的代码隐藏中将其定义为非静态 属性:
public ObservableCollection<Manufacturer> ManufacturerList { get; } = new ObservableCollection<Manufacturer>(new MyEntities().Manufacturers);
...你可以这样绑定它:
<DataGridComboBoxColumn Header="Manufacturer" SelectedValueBinding="{Binding ManufacturerID, Mode=TwoWay}"
SelectedValuePath="ID"
DisplayMemberPath="CompanyName">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.ManufacturerList, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.ManufacturerList, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
ID
和 CompanyName
应该是 Manufacturer
的 public 属性 class 和 ManufacturerID
是 public 属性 Product
class.
您需要在样式中设置 ItemsSource
属性 的原因是 DataGridComboBoxColumn
不是添加到元素树中的可视元素,因此它具有没有视觉祖先。
编辑:
So apparently the
DataContext
of yourUserControl
is aCollectionViewSource
. This is an example of why you should always provide a reproducible sample of your issue when asking a question.
无论如何,你可以在你的 UserControl
中定义另一个 CollectionViewSource
并将这个的 Source 设置为你的 Manufacturer
对象集合并像这样绑定列:
<DataGridComboBoxColumn ... ItemsSource="{Binding Source={StaticResource ManufacturerList}}" />
...其中 ManufacturerList
是 CollectionViewSource
的 x:Key
。