翼度科技»论坛 编程开发 .net 查看内容

EnableHeaderCheckBox导致空指针

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
GridViewCheckBoxColumn以CheckBox的形式显示、编辑bool值,实现行选中效果。
如果需要在表头添加全选框,可以将EnableHeaderCheckBox设置为true:
  1. private void AddCheckColumn()
  2. {
  3.     checkColumn = new GridViewCheckBoxColumn();
  4.     checkColumn.Name = "Select";
  5.     checkColumn.HeaderText = "All";
  6.     checkColumn.EnableHeaderCheckBox = true;
  7.     this.radGridView1.Columns.Insert(0, checkColumn);
  8.     this.radGridView1.HeaderCellToggleStateChanged += RadGridView1_HeaderCellToggleStateChanged;
  9. }
  10. private void RadGridView1_HeaderCellToggleStateChanged(object sender, GridViewHeaderCellEventArgs e)
  11. {
  12.     MessageBox.Show($"状态:{e.State}");
  13. }
复制代码
通过监听RadGridView的HeaderCellToggleStateChanged事件监听表头的全选框状态。除了切换表头的全选框状态时会触发该事件,切换列的CheckBox时如果同时切换了表头的全选框状态,也会触发该事件。
问题:

使用过程中,发现GridView隐藏再显示会报空指针异常。
分析

报错发生在GridView设置只读属性的位置,异常调用堆栈如下:
  1. at Telerik.WinControls.UI.GridCheckBoxHeaderCellElement.UpdateCheckboxReadOnly()
  2. at Telerik.WinControls.UI.GridCheckBoxHeaderCellElement.MasterTemplate_PropertyChanged(Object sender, PropertyChangedEventArgs e)
  3. at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
  4. at Telerik.WinControls.UI.GridViewTemplate.OnNotifyPropertyChanged(PropertyChangedEventArgs e)
  5. at Telerik.WinControls.UI.MasterGridViewTemplate.OnNotifyPropertyChanged(PropertyChangedEventArgs e)
  6. at Telerik.WinControls.UI.GridViewTemplate.SetProperty[T](String propertyName, T& propertyField, T value)
  7. at Telerik.WinControls.UI.MasterGridViewTemplate.set_GridReadOnly(Boolean value)
  8. at Telerik.WinControls.UI.RadGridView.set_ReadOnly(Boolean value)
  9. at CheckBoxInHeader_csharp.RadForm1.<AddButton>b__8_2(Object o, EventArgs e) in \CheckBoxInHeader_csharp\RadForm1.cs:line 82
复制代码
根据异常调用堆栈,发现是在Telerik内部报错,直接反编译调试下,在GridCheckBoxHeaderCellElement.UpdateCheckboxReadOnly()处设置断点,看看为什么导致空指针。查看this无法计算表达式,可以编辑下方法,加几个判断:

可以看到,this.ColumnInfo为空。继续调试,发现EnableHeaderCheckBox设置为true的列如果被隐藏,当设置GridView的Readonly属性的时候就会触发该异常,这是UI框架的BUG。
解决

可以自己实现GridCheckBoxHeaderCellElement,不用官方的,参考文档,这比较麻烦。简单处理,加个try-catch捕获下吧。以下是测试代码,先点击测试1,再点击测试2就会触发该异常。
  1. public partial class RadForm1 : RadForm
  2. {
  3.     private bool flag1 = false;
  4.     private bool flag2 = false;
  5.     private GridViewCheckBoxColumn checkColumn;
  6.     public RadForm1()
  7.     {
  8.         InitializeComponent();
  9.         AddCheckColumn();
  10.         AddButton();
  11.         this.radGridView1.RowCount = 10;
  12.         this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
  13.         this.radGridView1.MasterTemplate.AllowAddNewRow = false;
  14.     }
  15.     private void AddCheckColumn()
  16.     {
  17.         checkColumn = new GridViewCheckBoxColumn();
  18.         checkColumn.Name = "Select";
  19.         checkColumn.HeaderText = "All";
  20.         checkColumn.EnableHeaderCheckBox = true;
  21.         this.radGridView1.Columns.Insert(0, checkColumn);
  22.         this.radGridView1.HeaderCellToggleStateChanged += RadGridView1_HeaderCellToggleStateChanged;
  23.         this.radGridView1.Columns.Add(new GridViewTextBoxColumn("A"));
  24.         this.radGridView1.Columns.Add(new GridViewTextBoxColumn("B"));
  25.     }
  26.     private void RadGridView1_HeaderCellToggleStateChanged(object sender, GridViewHeaderCellEventArgs e)
  27.     {
  28.         MessageBox.Show($"状态:{e.State}");
  29.     }
  30.     private void AddButton()
  31.     {
  32.         Button btn1 = new Button();
  33.         btn1.Text = "测试1";
  34.         btn1.Click += (o, e) =>
  35.         {
  36.             checkColumn.IsVisible = flag1;
  37.             flag1 = !flag1;
  38.         };
  39.         btn1.Location = new Point(5, 5);
  40.         this.Controls.Add(btn1);
  41.         Button btn2 = new Button();
  42.         btn2.Text = "测试2";
  43.         btn2.Click += (o, e) =>
  44.         {
  45.             if (flag2)
  46.                 radGridView1.Hide();
  47.             else
  48.             {
  49.                 radGridView1.Show();
  50.                 try
  51.                 {
  52.                     radGridView1.ReadOnly = flag2;
  53.                 }
  54.                 catch { }
  55.             }
  56.             flag2 = !flag2;
  57.         };
  58.         btn2.Location = new Point(120, 5);
  59.         this.Controls.Add(btn2);
  60.     }
  61. }
复制代码
来源:https://www.cnblogs.com/louzixl/archive/2023/07/27/17585628.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具