Datagrid 组合框 selectionchanged 事件参数在两台电脑之间不同
Datagrid combobox selectionchanged event argument differ between two pc's
代码:
private void updateSeconderyCombobox(object sender, SelectionChangedEventArgs e)
{
object comboBox = null;
if (sender is ComboBox)
{
comboBox = (ComboBox)sender;
}
else
{
comboBox = (TextBlock)sender;
}
DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement((DependencyObject)comboBox);
xyEntry newValues = null;
if (row.Item != null)
{
newValues = (xyEntry)row.Item;
}
else
{
return;
}
Factors fs = new Factors();
List<Factor> list = fs.getFactors();
Factor f = list.Find(x => x.Category == newValues.Category);
newValues.FactorX = Convert.ToString(f.FactorXvalue);
newValues.FactorY = Convert.ToString(f.FactorYvalue);
newValues.SizeChoices = AddSeconderyCombobox(newValues.Category);
row.Item = null;
row.Item = newValues;
}
XAML:
<DataGrid SelectionUnit="FullRow" x:Name="dataGrid" Margin="10,110,162,15" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="X Coord" Binding="{Binding xCoord}" IsReadOnly="True" Width="*" />
<DataGridTextColumn Header="Y Coord" Binding="{Binding yCoord}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="Rotation" Binding="{Binding Rotation}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="RefDes" Binding="{Binding RefDes}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="P/N" Binding="{Binding Number}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="Package" Binding="{Binding Package}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="FactorX %" Binding="{Binding FactorX}" IsReadOnly="False" Width="*"/>
<DataGridTextColumn Header="FactorY %" Binding="{Binding FactorY}" IsReadOnly="False" Width="*"/>
<DataGridCheckBoxColumn Header="Use factors" Binding="{Binding UseFactors}" IsReadOnly="False" Width="*"/>
<DataGridTemplateColumn Header="Category" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox SelectedValue="{Binding Category, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding CategoryChoices}" SelectionChanged="updateSeconderyCombobox" >
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
<TextBlock Text="{Binding Category}" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Size" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox SelectedValue="{Binding Size, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding SizeChoices}">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
<TextBlock Text="{Binding Size}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
System.NullReferenceException
HResult=0x80004003 Message=Object reference not set to an instance of an object.
Source=IsoEasy
StackTrace: at
IsoEasy.Windows.Link_parts.updateSeconderyCombobox(Object sender,
SelectionChangedEventArgs e) at
System.Windows.Controls.SelectionChangedEventArgs.InvokeEventHandler(Delegate
genericHandler, Object genericTarget) at
System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object
target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object
target, RoutedEventArgs routedEventArgs) at
System.Windows.EventRoute.InvokeHandlersImpl(Object source,
RoutedEventArgs args, Boolean reRaised) at
System.Windows.UIElement.RaiseEventImpl(DependencyObject sender,
RoutedEventArgs args) at
System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) at
System.Windows.Controls.ComboBox.OnSelectionChanged(SelectionChangedEventArgs
e)
......
发生了什么:
Datagrid 的每一行包含 2 个组合框。第一个组合框是 6 个类别的静态列表,第二个组合框根据选择的类别进行填充。这在我测试过的 99% 的 PC 上运行良好。但是,我有一台 PC 出现了问题。错误发生在:
DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement((DependencyObject)comboBox);
xyEntry newValues = null;
if (row.Item != null){
newValues = (xyEntry)row.Item;
}
else {
return;
}
在这种情况下,我看到 sender 参数包含第一个组合框的静态列表。但是在这种不起作用的情况下,发件人似乎是一个空的组合框。这导致“行”变量被设置为空,当我在 if 语句中检查该变量的项目时,我得到一个 System.NullReferenceException
。
我尝试了什么:
- 首先,我确定安装了正确的 .Net 版本。这没有效果。
- 我尝试通过在将发件人的项目源转换为正确的数据类型后设置它来尝试修补程序,但这也会引发
NullReferenceException
.
- 相同的 windows 版本在两台机器上都是 运行
我认为 NullReferenceException 也有类似的问题,在为 row
赋值之前添加 DataGridRow row = new DataGridRow();
解决了这个问题。
请在尝试执行任何操作之前检查 ComboBox
是否已加载。您还应该避免转换为 FrameworkElement
:
以外的任何其他内容
private void updateSeconderyCombobox(object sender, SelectionChangedEventArgs e)
{
FrameworkElement comboBox = sender as FrameworkElement;
if (comboBox == null || !comboBox.IsLoaded)
return;
DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement(comboBox);
...
}
代码:
private void updateSeconderyCombobox(object sender, SelectionChangedEventArgs e)
{
object comboBox = null;
if (sender is ComboBox)
{
comboBox = (ComboBox)sender;
}
else
{
comboBox = (TextBlock)sender;
}
DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement((DependencyObject)comboBox);
xyEntry newValues = null;
if (row.Item != null)
{
newValues = (xyEntry)row.Item;
}
else
{
return;
}
Factors fs = new Factors();
List<Factor> list = fs.getFactors();
Factor f = list.Find(x => x.Category == newValues.Category);
newValues.FactorX = Convert.ToString(f.FactorXvalue);
newValues.FactorY = Convert.ToString(f.FactorYvalue);
newValues.SizeChoices = AddSeconderyCombobox(newValues.Category);
row.Item = null;
row.Item = newValues;
}
XAML:
<DataGrid SelectionUnit="FullRow" x:Name="dataGrid" Margin="10,110,162,15" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="X Coord" Binding="{Binding xCoord}" IsReadOnly="True" Width="*" />
<DataGridTextColumn Header="Y Coord" Binding="{Binding yCoord}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="Rotation" Binding="{Binding Rotation}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="RefDes" Binding="{Binding RefDes}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="P/N" Binding="{Binding Number}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="Package" Binding="{Binding Package}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="FactorX %" Binding="{Binding FactorX}" IsReadOnly="False" Width="*"/>
<DataGridTextColumn Header="FactorY %" Binding="{Binding FactorY}" IsReadOnly="False" Width="*"/>
<DataGridCheckBoxColumn Header="Use factors" Binding="{Binding UseFactors}" IsReadOnly="False" Width="*"/>
<DataGridTemplateColumn Header="Category" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox SelectedValue="{Binding Category, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding CategoryChoices}" SelectionChanged="updateSeconderyCombobox" >
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
<TextBlock Text="{Binding Category}" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Size" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox SelectedValue="{Binding Size, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding SizeChoices}">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
<TextBlock Text="{Binding Size}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=IsSelected}"
Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=IsoEasy StackTrace: at IsoEasy.Windows.Link_parts.updateSeconderyCombobox(Object sender, SelectionChangedEventArgs e) at System.Windows.Controls.SelectionChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) at System.Windows.Controls.ComboBox.OnSelectionChanged(SelectionChangedEventArgs e)
......
发生了什么: Datagrid 的每一行包含 2 个组合框。第一个组合框是 6 个类别的静态列表,第二个组合框根据选择的类别进行填充。这在我测试过的 99% 的 PC 上运行良好。但是,我有一台 PC 出现了问题。错误发生在:
DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement((DependencyObject)comboBox);
xyEntry newValues = null;
if (row.Item != null){
newValues = (xyEntry)row.Item;
}
else {
return;
}
在这种情况下,我看到 sender 参数包含第一个组合框的静态列表。但是在这种不起作用的情况下,发件人似乎是一个空的组合框。这导致“行”变量被设置为空,当我在 if 语句中检查该变量的项目时,我得到一个 System.NullReferenceException
。
我尝试了什么:
- 首先,我确定安装了正确的 .Net 版本。这没有效果。
- 我尝试通过在将发件人的项目源转换为正确的数据类型后设置它来尝试修补程序,但这也会引发
NullReferenceException
. - 相同的 windows 版本在两台机器上都是 运行
我认为 NullReferenceException 也有类似的问题,在为 row
赋值之前添加 DataGridRow row = new DataGridRow();
解决了这个问题。
请在尝试执行任何操作之前检查 ComboBox
是否已加载。您还应该避免转换为 FrameworkElement
:
private void updateSeconderyCombobox(object sender, SelectionChangedEventArgs e)
{
FrameworkElement comboBox = sender as FrameworkElement;
if (comboBox == null || !comboBox.IsLoaded)
return;
DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement(comboBox);
...
}