简体   繁体   English

Datagrid combobox selectionchanged 事件参数在两台电脑之间不同

[英]Datagrid combobox selectionchanged event argument differ between two pc's

Code:代码:

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: 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) 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)

...... ……

What occurs: Each row of the Datagrid contains 2 comboboxes.发生了什么:Datagrid 的每一行都包含 2 个组合框。 The first combobox is a static list of 6 categories, the second combobox get's populated depending on what category is selected.第一个 combobox 是一个包含 6 个类别的 static 列表,第二个 combobox 根据选择的类别填充。 This works fine on 99% of the PC's I've tested.这在我测试过的 99% 的 PC 上运行良好。 However, I have one PC where this gives a problem.但是,我有一台 PC 出现了问题。 The error occurs on:错误发生在:

DataGridRow row = (DataGridRow)dataGrid.ContainerFromElement((DependencyObject)comboBox);
xyEntry newValues = null;

if (row.Item != null){
    newValues = (xyEntry)row.Item;
}
else {
    return;
}

In the situation where this works, I see that the sender parameter contains the static list for the first combobox. But in this one case where this doesn't work the sender seems to be an empty combobox. This results in the fact that "row" variable gets set as null and I get a System.NullReferenceException when I check the items of this variable in the if statement.在这种情况下,我看到发件人参数包含第一个 combobox 的 static 列表。但在这种情况下,发件人似乎是空的 combobox。这导致“行“变量设置为 null,当我在 if 语句中检查此变量的项目时,我得到一个System.NullReferenceException

What I tried:我尝试了什么:

  • First of all, I made sure the correct.Net version was installed.首先,我确保安装了正确的 .Net 版本。 This had no effect.这没有效果。
  • I tried a hotfix by trying to set the itemsource of the sender after casting it to the correct data type, but this also throws a NullReferenceException .我尝试了一个修补程序,方法是在将发件人的项目源转换为正确的数据类型后尝试设置它,但这也会引发NullReferenceException
  • The same windows versions are running on both machines相同的 windows 版本在两台机器上运行

I think I had a similar issue with NullReferenceException and adding DataGridRow row = new DataGridRow();我想我对 NullReferenceException 和添加DataGridRow row = new DataGridRow();有类似的问题before assigning value to row solved this problem.在为row分配值之前解决了这个问题。

Check whether the ComboBox has been loaded before you try to do anything.在尝试执行任何操作之前,请检查ComboBox是否已加载。 You should also avoid casting to anything else than a FrameworkElement :您还应该避免强制转换为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);
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM