DataGrid 中的 WPF Combobox - SelectionChanged 事件将选定的 ComboBoxItem 返回为 null
WPF Combox in DataGrid - SelectionChanged event returning selected ComboBoxItem as null
问题:在DataGrid
的Combobox的SelectionChanged
事件中,ComboboxItem
始终为null。我可能遗漏了什么以及我们如何解决这个问题?请注意(如图 1 所示)如果您能够从组合框中 select 一个项目,这意味着组合框已经加载。因此它的 SelectionChanged
事件在组合框加载后被调用。
Employee.cs:
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string StateName { get; set; }
}
State.cs:
public class State
{
public string StateName { get; set; }
public string StateCode { get; set; }
}
StateList.cs:
public class StateList : List<State>
{
public StateList()
{
Add(new State { StateName = "Iowa", StateCode = "IA" });
Add(new State { StateName = "Nebraska", StateCode = "NE" });
Add(new State { StateName = "Ohio", StateCode = "OH" });
Add(new State { StateName = "Virginia", StateCode = "VA" });
}
}
Combobox SelectionChanged 事件 [always returns cmbItem as null]:
private void cmbState_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
StateList states = new StateList();
string st = "";
ComboBoxItem cmbItem = ((sender as ComboBox).SelectedItem as ComboBoxItem);
if(cmbItem != null)
st = " You selected " + cmbItem.Content.ToString() + ".";
}
更改 selection 的快照:
ComboboxItem 显示为 null:
MainWindow.xaml:
<Window x:Class="WPF_DataGridCombobox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
.......
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:StateList x:Key="ListOfStates"/>
</Window.Resources>
<Grid>
<DataGrid x:Name="dgEmplyees" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Update">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btnUpdate" Click="btnUpdate_Click"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTemplateColumn Header="State Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StateName}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="cmbState" ItemsSource="{StaticResource ListOfStates}" DisplayMemberPath="StateName" SelectedValuePath="StateName" SelectedValue="{Binding StateName}" SelectionChanged="cmbState_SelectionChanged" IsEditable="False" IsReadOnly="True" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
我无法添加评论,所以我写在这里。
在 microsoft 的示例中,他们将 ListBoxItem
类型的对象添加到列表框。所以这里SelectedItem
可以解析为ListBoxItem
。
但是您使用列表 ListOfStates
,因此 SelectedItem
的类型为 State
。因此你必须写:State state = ((sender as ComboBox).SelectedItem as State);
((ComboBox)sender).SelectedItem as ComboBoxItem
是 null
因为 SelectedItem 不是 ComboBoxItem。如果您明确添加了 ComboBoxItems,它将是一个 ComboBoxItem,例如喜欢
<ComboBox>
<ComboBoxItem>Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
<ComboBox>
由于您已将一组 State 对象分配给 ComboBox 的 ItemsSource 属性,因此 SelectedItem 是一个 State 对象:
private void cmbState_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var state = (State)((ComboBox)sender).SelectedItem;
...
}
问题:在DataGrid
的Combobox的SelectionChanged
事件中,ComboboxItem
始终为null。我可能遗漏了什么以及我们如何解决这个问题?请注意(如图 1 所示)如果您能够从组合框中 select 一个项目,这意味着组合框已经加载。因此它的 SelectionChanged
事件在组合框加载后被调用。
Employee.cs:
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string StateName { get; set; }
}
State.cs:
public class State
{
public string StateName { get; set; }
public string StateCode { get; set; }
}
StateList.cs:
public class StateList : List<State>
{
public StateList()
{
Add(new State { StateName = "Iowa", StateCode = "IA" });
Add(new State { StateName = "Nebraska", StateCode = "NE" });
Add(new State { StateName = "Ohio", StateCode = "OH" });
Add(new State { StateName = "Virginia", StateCode = "VA" });
}
}
Combobox SelectionChanged 事件 [always returns cmbItem as null]:
private void cmbState_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
StateList states = new StateList();
string st = "";
ComboBoxItem cmbItem = ((sender as ComboBox).SelectedItem as ComboBoxItem);
if(cmbItem != null)
st = " You selected " + cmbItem.Content.ToString() + ".";
}
更改 selection 的快照:
ComboboxItem 显示为 null:
MainWindow.xaml:
<Window x:Class="WPF_DataGridCombobox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
.......
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:StateList x:Key="ListOfStates"/>
</Window.Resources>
<Grid>
<DataGrid x:Name="dgEmplyees" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Update">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btnUpdate" Click="btnUpdate_Click"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTemplateColumn Header="State Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StateName}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="cmbState" ItemsSource="{StaticResource ListOfStates}" DisplayMemberPath="StateName" SelectedValuePath="StateName" SelectedValue="{Binding StateName}" SelectionChanged="cmbState_SelectionChanged" IsEditable="False" IsReadOnly="True" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
我无法添加评论,所以我写在这里。
在 microsoft 的示例中,他们将 ListBoxItem
类型的对象添加到列表框。所以这里SelectedItem
可以解析为ListBoxItem
。
但是您使用列表 ListOfStates
,因此 SelectedItem
的类型为 State
。因此你必须写:State state = ((sender as ComboBox).SelectedItem as State);
((ComboBox)sender).SelectedItem as ComboBoxItem
是 null
因为 SelectedItem 不是 ComboBoxItem。如果您明确添加了 ComboBoxItems,它将是一个 ComboBoxItem,例如喜欢
<ComboBox>
<ComboBoxItem>Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
<ComboBox>
由于您已将一组 State 对象分配给 ComboBox 的 ItemsSource 属性,因此 SelectedItem 是一个 State 对象:
private void cmbState_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var state = (State)((ComboBox)sender).SelectedItem;
...
}