Аргумент события изменения поля со списком данных Datagrid отличается между двумя p c - PullRequest
0 голосов
/ 04 августа 2020

Код:

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 Сообщение = Ссылка на объект не установлена ​​на экземпляр объекта. Источник = IsoEasy StackTrace: в IsoEasy. Windows .Link_parts.updateSeconderyCombobox (отправитель объекта, SelectionChangedEventArgs e) в System. Windows .Controls.SelectionChangedEventArgs.InvokeEventHandler (Делегировать genericToungedEventArgs. *. InvokeHandler (обработчик делегата, цель объекта) в System. Windows .RoutedEventHandlerInfo.InvokeHandler (цель объекта, RoutedEventArgs routedEventArgs) в System. Windows .EventRoute.InvokeHandlersImpl (источник объекта, RoutedEventArgs с аргументами *. * .UIElement.RaiseEventImpl (отправитель DependencyObject, аргументы RoutedEventArgs) в системе. Windows .UIElement.RaiseEvent (RoutedEventArgs e) в системе. Windows .Controls.ComboBox.OnSelectionChanged (SelectionChangedEventArgs) 100 * 10 * 10 * 10 e) * ......

Что происходит: Каждая строка Datagrid содержит 2 поля со списком. Первое поле со списком - это статический c список из 6 категорий, второе поле со списком заполняется в зависимости от выбранной категории. Это отлично работает на 99% P C, которые я тестировал. Однако у меня есть один P C, где это создает проблему. Ошибка возникает:

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

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

В ситуации, когда это работает, я вижу, что параметр отправителя содержит список stati c для первого поля со списком. Но в этом случае, когда это не работает, отправитель кажется пустым списком. Это приводит к тому, что переменная "row" получает значение null, и я получаю System.NullReferenceException, когда проверяю элементы этой переменной в операторе if.

Что я пробовал:

  • Прежде всего, я убедился, что установлена ​​правильная версия. Net. Это не имело никакого эффекта.
  • Я попробовал исправить, попытавшись установить источник элементов отправителя после его преобразования в правильный тип данных, но это также выдает NullReferenceException.
  • То же самое windows версии работают на обеих машинах

Ответы [ 2 ]

0 голосов
/ 04 августа 2020

Проверьте, загружен ли 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);
    ...
}
0 голосов
/ 04 августа 2020

Думаю, у меня была аналогичная проблема с NullReferenceException, и добавление DataGridRow row = new DataGridRow(); перед присвоением значения row решило эту проблему.

...