locked
NullReferenceException was unhandled C# RRS feed

  • Question

  • Hi all,

    I have a dataGrid and in this a few columns. There is also a checkbox (es) with function _Checked() and _Unchecked().

    When the checkBox is Checked, the column in the datagrid should be Visible => Unchecked = Collapsed,

    So ... inside this function it show me an error An exception of type 'System.NullReferenceException' occurred in Program 2018.exe but was not handled in user code

    Part of my code ...

    private void chckName_Checked(object sender, RoutedEventArgs e)
    {
        dtgMain.Columns[4].Visibility = Visibility.Visible;
    }
    What sholud I do? Thanks

    Tuesday, July 2, 2019 9:39 AM

All replies

  • Hi,
    when call the method chckName_Checked in dtgMain is no Columns[4].

    In WPF is better to bind Visibility to a property and bind the Checkbox to the same property (with type conversion, e.g. converter).


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Tuesday, July 2, 2019 9:58 AM
  • Can you give an example, please? I down know how. What is strange, yesterday it works well. No idea what is wrong.

    Tuesday, July 2, 2019 10:08 AM
  • Hi,
    try this demo:

    XAML:

    <Window x:Class="WpfApp1.Window41"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window41" Height="450" Width="800">
      <Window.Resources>
        <local:Window41Converter x:Key="conv"/>
        <local:Window41VM x:Key="vm"/>
      </Window.Resources>
        <StackPanel DataContext="{StaticResource vm}">
        <CheckBox Content="chckName" IsChecked="{Binding IsChecked}"/>
        <DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="false">
          <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
            <DataGridTextColumn Header="Info" Binding="{Binding Info}" 
                                Visibility="{Binding IsChecked, Converter={StaticResource conv}, Source={StaticResource vm}}"/>
          </DataGrid.Columns>
        </DataGrid>
      </StackPanel>
    </Window>

    Classes:

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Globalization;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WpfApp1
    {
      /// <summary>
      /// Interaction logic for Window41.xaml
      /// </summary>
      public partial class Window41 : Window
      {
        public Window41()
        {
          InitializeComponent();
        }
      }
    
      public class Window41VM : INotifyPropertyChanged
      {
        /// <summary>
        /// constructor to generate demo data
        /// </summary>
        public Window41VM()
        {
          for (int i = 0; i < 10; i++) col.Add(new Window41Data() { ID = i, Info = $"Row {i}" });
          cvs.Source = col;
        }
    
        /// <summary>
        /// collection of demo data
        /// </summary>
        ObservableCollection<Window41Data> col = new ObservableCollection<Window41Data>();
    
        /// <summary>
        /// proxy for view of data in collection
        /// </summary>
        CollectionViewSource cvs = new CollectionViewSource();
    
        /// <summary>
        /// property for binding for display data from collection
        /// </summary>
        public ICollectionView View { get { return cvs.View; } }
    
        /// <summary>
        /// backing field for IsChecked property
        /// </summary>
        private bool _isChecked = true;
    
        /// <summary>
        /// propeerty for binding to CheckBox and Visibility of column
        /// </summary>
        public bool IsChecked { get { return this._isChecked; } set { this._isChecked = value; OnPropertyChanged(); } }
    
        #region  OnPropertyChanged - to signal changes to the data for the display
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
      }
    
      /// <summary>
      /// class for keeping data
      /// </summary>
      public class Window41Data
      {
        public int ID { get; set; }
        public string Info { get; set; }
      }
    
      /// <summary>
      /// Converter for binding a bool value to Visibility property
      /// </summary>
      public class Window41Converter : IValueConverter
      {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
           ((bool)value) ? Visibility.Visible : Visibility.Hidden;
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
          throw new NotImplementedException();
      }
    }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    • Edited by Peter Fleischer Tuesday, July 2, 2019 2:01 PM add comment for better unterstanding
    Tuesday, July 2, 2019 11:30 AM
  • Hi, 

    I am not so good in programming. I creaded som programs, but I am trying to use code that I understand ... I did it it in a simple way .. for now ... I will learn your code .. to understand it 

    instead

    dtgMain.Columns[4].Visibility = Visibility.Visible;

    I did

    try{ dtgMain.Columns[4].Visibility = Visibility.Visible; }catch(Exception ex){  }

    what you say on this code/ this way

    Tuesday, July 2, 2019 1:18 PM
  • Hi,
    I add comments to my demo for better unterstanding.

    To ignore errors is a bad idea. Better is to check the column count like this:

          if (dtgMain.Columns.Count>4) dtgMain.Columns[4].Visibility = Visibility.Visible;
    


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Tuesday, July 2, 2019 2:10 PM
  • You can see the number of columns de grid have: 

    var numberColumns = dtgMain.Columns

    If number columns is 4 you need use:

    dtgMain.Columns[3]

    Because have 4 index but the index start in 0! (0, 1, 2, 3)

    If have 4 index and you try get the index [4] you got a nullreference.

    Tuesday, July 2, 2019 2:42 PM
  • I have about 12 columns. I knwo it start from 0 :-)

    Wednesday, July 3, 2019 6:16 AM
  • Hi   TakeshiKitano, 

    I have tested the following code. It is working.

    <Grid>
            <DataGrid x:Name="MyDataGrid"    Margin="0,0,0,117">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="A"  />
                    <DataGridTextColumn Header="B"  />
                    <DataGridTextColumn Header="C" />
                    <DataGridTemplateColumn  Width="150" Header="E">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <TextBox Height="28"  Text="hello E" >
                                    </TextBox>
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn  Width="150" Header="F">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <TextBox Height="28"  Text="hello F" >
                                    </TextBox>
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
    
                </DataGrid.Columns>
            </DataGrid>
           
            <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="318,336,0,0" VerticalAlignment="Top" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
        </Grid>
    
     private void CheckBox_Checked(object sender, RoutedEventArgs e)
            {
                MyDataGrid.Columns[4].Visibility = Visibility.Visible;
            }
    
            private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
            {
                MyDataGrid.Columns[4].Visibility = Visibility.Hidden;
            }
    
    If I have any misunderstanding, you can include all necessary code snippets for anyone else to be able to reproduce your issue from scratch along with a detailed description about the results including any exception messages 

    This will help us quickly analyze your problem.


    Best regards

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 3, 2019 6:55 AM
  • OK, I am going to do it in your way. Bu one more question. It is possible with BooleanToVisibilityConverter ? It should be in using System.Windows.Controls;
    Wednesday, July 3, 2019 10:42 AM
  • Hi   TakeshiKitano,

    >> OK, I am going to do it in your way. Bu one more question. It is possible with BooleanToVisibilityConverter ? It should be in using System.Windows.Controls;

    Peter has given you  a sample about how to use a Converter(Window41Converter).

    You can use the BooleanToVisibilityConverter.

        <Window.Resources>
            <BooleanToVisibilityConverter x:Key="BoolToVis"/>
        </Window.Resources>
        <Grid>
            <Button Visibility="{Binding valueCancel, Converter={StaticResource BoolToVis}   }"  />
        </Grid>
    Besides, It would be appreciated if you could close the thread by marking helpful posts as an answer. This will help other members to find the solution quickly if they have faced the similar issue. If you have a new question you can start a new thread. Please don't ask several questions in the same thread.

    Thank you for your understanding.

    Best regards

    Yong Lu

     

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, July 4, 2019 2:35 AM
  • Thanks. I already do it. It works on button forexample, but on datagrid row it doesnt. No idea why.

    It is very simple and elegant solution ... but why it doesnt work on it ... dont know

    Thursday, July 4, 2019 6:19 AM
  • Thanks. I already do it. It works on button forexample, but on datagrid row it doesnt. No idea why.

    It is very simple and elegant solution ... but why it doesnt work on it ... dont know

    Hi    TakeshiKitano,


    If you have some problem with the BooleanToVisibilityConverter using, you can start a new thread  with all necessary code snippets for anyone else to be able to reproduce your issue from scratch along with a detailed description about the results including any exception messages.

    Thank you for your understanding.

    Best regards

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, July 4, 2019 6:41 AM
  • Hi,
    in my demo it works without problems (in columns):

    XAML:

    <Window x:Class="WpfApp1.Window41"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window41" Height="450" Width="800">
      <Window.Resources>
        <BooleanToVisibilityConverter x:Key="conv"/>
        <local:Window41VM x:Key="vm"/>
      </Window.Resources>
        <StackPanel DataContext="{StaticResource vm}">
        <CheckBox Content="chckName" IsChecked="{Binding IsChecked}"/>
        <DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="false">
          <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
            <DataGridTextColumn Header="Info" Binding="{Binding Info}" 
                                Visibility="{Binding IsChecked, Converter={StaticResource conv}, Source={StaticResource vm}}"/>
          </DataGrid.Columns>
        </DataGrid>
      </StackPanel>
    </Window>

    ViewModel:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WpfApp1
    {
      public class Window41VM : INotifyPropertyChanged
      {
        /// <summary>
        /// constructor to generate demo data
        /// </summary>
        public Window41VM()
        {
          for (int i = 0; i < 10; i++) col.Add(new Window41Data() { ID = i, Info = $"Row {i}" });
          cvs.Source = col;
        }
    
        /// <summary>
        /// collection of demo data
        /// </summary>
        ObservableCollection<Window41Data> col = new ObservableCollection<Window41Data>();
    
        /// <summary>
        /// proxy for view of data in collection
        /// </summary>
        CollectionViewSource cvs = new CollectionViewSource();
    
        /// <summary>
        /// property for binding for display data from collection
        /// </summary>
        public ICollectionView View { get { return cvs.View; } }
    
        /// <summary>
        /// backing field for IsChecked property
        /// </summary>
        private bool _isChecked = true;
    
        /// <summary>
        /// propeerty for binding to CheckBox and Visibility of column
        /// </summary>
        public bool IsChecked { get { return this._isChecked; } set { this._isChecked = value; OnPropertyChanged(); } }
    
        #region  OnPropertyChanged - to signal changes to the data for the display
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
      }
    
      /// <summary>
      /// class for keeping data
      /// </summary>
      public class Window41Data
      {
        public int ID { get; set; }
        public string Info { get; set; }
      }
    }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    • Edited by Peter Fleischer Thursday, July 4, 2019 7:37 AM
    • Proposed as answer by Misty Zi Monday, July 22, 2019 1:25 AM
    Thursday, July 4, 2019 7:36 AM