WPF中Infragistics XamDataGrid相对源绑定引发空引用异常
解决Infragistics XamDataGrid行为绑定后NullReferenceException问题
你遇到的核心问题是:修改OwnerXamDataGrid的绑定方式后,这个属性没有正确获取到XamDataGrid实例,导致订阅DataValueChanged事件时触发空引用异常。下面我来拆解原因并给出具体解决方案:
为什么原绑定能正常工作?
你最初使用的RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type igDP:XamDataGrid}}是有效的,因为HeaderPrefixArea属于XamDataGrid视觉树的一部分,通过FindAncestor可以向上定位到父级的XamDataGrid实例,绑定完成后OwnerXamDataGrid会被正确赋值,所以订阅事件不会出错。
修改绑定后出现空引用的常见原因
- 绑定表达式错误:比如误用了
RelativeSource=Self(HeaderPrefixArea本身不是XamDataGrid),或者AncestorType拼写错误、AncestorLevel设置不当(如果存在嵌套的XamDataGrid)。 - 绑定时机问题:你的行为可能在绑定完成前就执行了订阅代码(比如在构造函数或
OnAttached方法里直接访问OwnerXamDataGrid),此时属性还未被赋值,自然会为空。
具体解决方案
1. 确保绑定表达式能正确定位XamDataGrid
根据你的场景,推荐两种可靠的绑定方式:
- 验证FindAncestor参数:如果必须修改绑定,确认
AncestorType是正确的igDP:XamDataGrid,若存在多层嵌套控件,可调整AncestorLevel:local:RectangleBehavior OwnerXamDataGrid="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type igDP:XamDataGrid}, AncestorLevel=1}}" - 使用ElementName绑定:给XamDataGrid设置
x:Name,直接绑定到该名称(注意命名空间作用域要覆盖HeaderPrefixArea):<igDP:XamDataGrid x:Name="MyDataGrid" ...> <!-- HeaderPrefixArea样式定义 --> <Style TargetType="igDP:HeaderPrefixArea"> <Setter Property="local:RectangleBehavior.OwnerXamDataGrid" Value="{Binding ElementName=MyDataGrid}" /> </Style> </igDP:XamDataGrid>
2. 调整行为的事件订阅逻辑,避免空引用
不要在绑定完成前直接访问OwnerXamDataGrid,而是通过依赖属性的变更回调来处理事件的订阅与取消。修改你的RectangleBehavior代码:
public class RectangleBehavior : Behavior<UIElement> { public static readonly DependencyProperty OwnerXamDataGridProperty = DependencyProperty.Register( nameof(OwnerXamDataGrid), typeof(XamDataGrid), typeof(RectangleBehavior), new PropertyMetadata(null, OnOwnerXamDataGridChanged)); public XamDataGrid OwnerXamDataGrid { get => (XamDataGrid)GetValue(OwnerXamDataGridProperty); set => SetValue(OwnerXamDataGridProperty, value); } private static void OnOwnerXamDataGridChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var behavior = (RectangleBehavior)d; var oldGrid = e.OldValue as XamDataGrid; var newGrid = e.NewValue as XamDataGrid; // 取消旧网格的事件订阅 if (oldGrid != null) { oldGrid.DataValueChanged -= behavior.OnDataValueChanged; } // 仅当新网格不为空时,订阅事件 if (newGrid != null) { newGrid.DataValueChanged += behavior.OnDataValueChanged; } } private void OnDataValueChanged(object sender, DataValueChangedEventArgs e) { // 你的事件处理逻辑 } // 可选:行为分离时取消订阅,避免内存泄漏 protected override void OnDetaching() { base.OnDetaching(); if (OwnerXamDataGrid != null) { OwnerXamDataGrid.DataValueChanged -= OnDataValueChanged; } } }
这种方式会在OwnerXamDataGrid属性被正确赋值(绑定完成)后再订阅事件,从根源上避免空引用异常。
3. 调试技巧
如果问题仍存在,可以在OnOwnerXamDataGridChanged方法中添加断点,查看e.NewValue是否为null,以此判断绑定是否生效;也可以使用WPF绑定调试工具(如Snoop)检查绑定状态,确认是否存在绑定错误。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

