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

我尝试了什么:

我认为 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);
    ...
}