加载序列化DisplayLayout后UltraGridRow的ListObject为何为null?
我在WinForms应用中使用Infragistics UltraGrid(v13.1),最近加了一段代码:用二进制序列化保存网格布局,然后通过DisplayLayout.CopyFrom方法加载布局。加载后网格显示正常,数据也正确,但获取任意行的ListObject时都返回null。网格的数据源是BindingSource,它的DataSource是BindingList,加载布局时数据没有变化。
保存布局的代码:
Dim MS As New IO.MemoryStream() ugl.Save(MS, Infragistics.Win.UltraWinGrid.PropertyCategories.All) Return MS.ToArray()
加载布局的代码:
Private Function ConvertToUltraGridLayout(data As Byte()) As UltraGridLayout Dim ugl As New UltraGridLayout() Dim MS As New IO.MemoryStream(data) MS.Seek(0, IO.SeekOrigin.Begin) ugl.Load(MS, Infragistics.Win.UltraWinGrid.PropertyCategories.All) Return ugl End Function dgrServices.DisplayLayout.CopyFrom(ConvertToUltraGridLayout(lOption.Layout))
请问要怎么操作才能让ListObject不为null?
解决思路与方案
这个问题我之前也碰到过,根源在于你用了PropertyCategories.All来序列化和加载布局——这个选项会把数据绑定相关的属性也一起保存,加载后这些属性会覆盖当前网格和数据源的关联,导致行无法正确映射到ListObject。下面是具体的解决步骤:
1. 缩小序列化的属性范围,排除数据绑定相关类别
不要用PropertyCategories.All,只保存和布局外观、结构相关的属性(比如列宽、顺序、分组、排序、样式这些),避开数据绑定的部分。修改你的保存和加载代码:
保存代码修改后:
Dim MS As New IO.MemoryStream() ' 只保存布局和外观类别的属性,排除数据绑定 ugl.Save(MS, Infragistics.Win.UltraWinGrid.PropertyCategories.Layout Or Infragistics.Win.UltraWinGrid.PropertyCategories.Appearance) Return MS.ToArray()
加载代码修改后:
Private Function ConvertToUltraGridLayout(data As Byte()) As UltraGridLayout Dim ugl As New UltraGridLayout() Dim MS As New IO.MemoryStream(data) MS.Seek(0, IO.SeekOrigin.Begin) ' 和保存时用相同的属性类别 ugl.Load(MS, Infragistics.Win.UltraWinGrid.PropertyCategories.Layout Or Infragistics.Win.UltraWinGrid.PropertyCategories.Appearance) Return ugl End Function dgrServices.DisplayLayout.CopyFrom(ConvertToUltraGridLayout(lOption.Layout))
这样只会加载那些不会影响数据源关联的布局设置,不会破坏行和ListObject的映射关系。
2. (可选)加载布局后重新绑定数据源(兜底方案)
如果上面的方法还没解决,可以尝试在加载布局后,重新触发一次数据源绑定,强制网格重新关联行和数据源对象:
' 先保存当前数据源 Dim tempBindingSource = dgrServices.DataSource ' 解绑再重新绑定 dgrServices.DataSource = Nothing dgrServices.DataSource = tempBindingSource
这个操作会让网格重新遍历数据源,重建行和ListObject的关联,一般能解决绑定脱节的问题。
3. 验证布局文件的内容(进阶排查)
如果还是有问题,可以检查一下序列化的布局数据里是否包含了DataBinding相关的节点。你可以把内存流的内容保存成文件,用文本编辑器打开(二进制序列化的话可能不太好读,但v13.1也支持XML序列化,你可以临时换成XML格式排查),确认没有意外保存的绑定属性。
内容的提问来源于stack exchange,提问作者StringbeanNinja

