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:
<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)
......
What occurs: Each row of the Datagrid contains 2 comboboxes. The first combobox is a static list of 6 categories, the second combobox get's populated depending on what category is selected. This works fine on 99% of the PC's I've tested. However, I have one PC where this gives a problem. 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.
What I tried:
NullReferenceException
.I think I had a similar issue with NullReferenceException and adding DataGridRow row = new DataGridRow();
before assigning value to row
solved this problem.
Check whether the ComboBox
has been loaded before you try to do anything. You should also avoid casting to anything else than a 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);
...
}
User contributions licensed under CC BY-SA 3.0