WPF- 将更改事件添加到自动生成的 DataGridComboBoxColumn
WPF- Add change event to autogenerated DataGridComboBoxColumn
我有一个数据网格,在 DataGrid.AutoGeneratingColumn
事件中我将一些列更改为 DataGridComboBoxColumns。
同时我还想向那个新的组合框添加一个选择更改事件,但不知道如何访问 DataGridComboBoxColumn 中的组合框控件。
private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var cb = new DataGridComboBoxColumn();
switch (e.PropertyName)
{
case "name":
using (Entities context = new Entities())
{
List<object> fNames = (from x in context.view
select new object {objectname = x.objectname}).ToList<object>();
cb.Header = "xxx";
cb.ItemsSource = xxx;
cb.SelectedItemBinding = new Binding("xxx");
e.Column = cb;
//Get reference to combobox in this new column
//Add event to it
//?????
}
break;
//more ....
}
}
为什么不在xaml中声明列,并为每一列提供列模板?然后您可以订阅选择更改事件。或者,改为绑定到 "SelectedItem" 组合框 属性。
例如,您可以为 ProductA 提供一个 DataTemplate,其中包含数据网格和 ProductA[=22] 的特定列=];同样适用于 ProductB.
<DataTemplate DataType="{x:Type model:ProductA}">
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Products}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ProductName}"
Header="ProductName"
IsReadOnly="True"></DataGridTextColumn>
<DataGridTemplateColumn Header="Category">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CategoryName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedCategory"}
IsSynchronizedWithCurrentItem="True" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
然后要使用数据模板,您将使用 ContentPresenter,它会根据 SelectedProduct 类型解析正确的数据模板。
<ContentPresenter Content="{Binding SelectedProductType}" />
您无法从 DataGrid.AutoGeneratingColumn 事件处理程序访问 ComboBox 实例,因为 ComBox 仅在该列的单元格进入编辑模式时创建,并且每次该单元格进入编辑模式时都会创建新的 ComboBox 实例。
这是一个示例代码,如何通过 DataGridComboBoxColumn.EditingElementStyle property by setting EventSetter for Selector.SelectionChangedEvent(ComboBox 继承自 Selector)来执行您想要的操作:
private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
switch (e.PropertyName)
{
case "name":
var cb = new DataGridComboBoxColumn();
// Old...
cb.Header = "Name";
cb.ItemsSource = new List<string>() { "Option1", "Option2", "Option3" };
cb.SelectedItemBinding = new Binding("name");
// NEW
cb.EditingElementStyle = new Style(typeof(ComboBox))
{
Setters =
{
new EventSetter(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(OnComboBoxSelectionChanged))
}
};
e.Column = cb;
break;
}
}
private static void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// We must check that both RemovedItems and AddedItems are not empty,
// because this event also fires when ComboBox is initialized (when entering edit mode), but then RemovedItems is empty.
if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0)
{
var newlySelectedName = (string)e.AddedItems[0];
}
}
我有一个数据网格,在 DataGrid.AutoGeneratingColumn
事件中我将一些列更改为 DataGridComboBoxColumns。
同时我还想向那个新的组合框添加一个选择更改事件,但不知道如何访问 DataGridComboBoxColumn 中的组合框控件。
private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var cb = new DataGridComboBoxColumn();
switch (e.PropertyName)
{
case "name":
using (Entities context = new Entities())
{
List<object> fNames = (from x in context.view
select new object {objectname = x.objectname}).ToList<object>();
cb.Header = "xxx";
cb.ItemsSource = xxx;
cb.SelectedItemBinding = new Binding("xxx");
e.Column = cb;
//Get reference to combobox in this new column
//Add event to it
//?????
}
break;
//more ....
}
}
为什么不在xaml中声明列,并为每一列提供列模板?然后您可以订阅选择更改事件。或者,改为绑定到 "SelectedItem" 组合框 属性。
例如,您可以为 ProductA 提供一个 DataTemplate,其中包含数据网格和 ProductA[=22] 的特定列=];同样适用于 ProductB.
<DataTemplate DataType="{x:Type model:ProductA}">
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Products}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ProductName}"
Header="ProductName"
IsReadOnly="True"></DataGridTextColumn>
<DataGridTemplateColumn Header="Category">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CategoryName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedCategory"}
IsSynchronizedWithCurrentItem="True" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
然后要使用数据模板,您将使用 ContentPresenter,它会根据 SelectedProduct 类型解析正确的数据模板。
<ContentPresenter Content="{Binding SelectedProductType}" />
您无法从 DataGrid.AutoGeneratingColumn 事件处理程序访问 ComboBox 实例,因为 ComBox 仅在该列的单元格进入编辑模式时创建,并且每次该单元格进入编辑模式时都会创建新的 ComboBox 实例。
这是一个示例代码,如何通过 DataGridComboBoxColumn.EditingElementStyle property by setting EventSetter for Selector.SelectionChangedEvent(ComboBox 继承自 Selector)来执行您想要的操作:
private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
switch (e.PropertyName)
{
case "name":
var cb = new DataGridComboBoxColumn();
// Old...
cb.Header = "Name";
cb.ItemsSource = new List<string>() { "Option1", "Option2", "Option3" };
cb.SelectedItemBinding = new Binding("name");
// NEW
cb.EditingElementStyle = new Style(typeof(ComboBox))
{
Setters =
{
new EventSetter(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(OnComboBoxSelectionChanged))
}
};
e.Column = cb;
break;
}
}
private static void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// We must check that both RemovedItems and AddedItems are not empty,
// because this event also fires when ComboBox is initialized (when entering edit mode), but then RemovedItems is empty.
if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0)
{
var newlySelectedName = (string)e.AddedItems[0];
}
}