代码之家  ›  专栏  ›  技术社区  ›  Tor Haugen

wpf sentinel对象以及如何检查内部类型

  •  27
  • Tor Haugen  · 技术社区  · 14 年前

    正如你们中的一些人所发现的,一个新特性(?)出现了WPF 4,其中数据绑定引擎可以传递类的自定义控件实例 ms.internal.name对象 以“ 断开连接项 “进入DataContext-而不是您的代码期望的数据项(当模板化控件被其itemsControl断开连接时会发生这种情况)。这些被称为哨兵对象。

    在现有的代码中,这可能导致错误的异常,因为代码没有为它做好准备。这些可能会被数据绑定子系统所吞噬,或者会造成严重的破坏。注意调试控制台。

    不管怎样,我是在 this MSDN forum . 还有萨姆·本特的一个帖子 explains it all . 现在去读吧, 你会想知道的 . 本质上,这些事件不应该触发(这就是bug),因此:

    忽略DataContextChanged事件,如果 DataContext是Sentinel对象。

    所以,我想检查一下我的数据上下文。但是如何呢?考虑:

    public bool IsSentinelObject(object dataContext)
    {
        return (dataContext is MS.Internal.NamedObject);
    }
    

    猜猜怎么回事?它不会编译,因为ms.internal.namedObject是内部的,我无法访问。当然,我可以这样破解:

    public bool IsSentinelObject(object dataContext)
    {
        return dataContext.GetType().FullName == "MS.Internal.NamedObject"
               || dataContext.ToString() == "{DisconnectedObject}";
    }
    

    (或者其他有用的东西)。我还遵循了Sam的建议,缓存对象以备日后进行引用相等性检查(它是单例)。

    当然,这意味着我没有问题,不是真的。但我很好奇,这篇文章肯定会让一些用户受益,所以还是值得问一下:

    是否有一种方法可以在不进行字符串比较的情况下,根据内部namedObject类型精确检查该类型?

    2 回复  |  直到 11 年前
        1
  •  16
  •   dtb    14 年前

    var disconnectedItem = typeof(System.Windows.Data.BindingExpressionBase)
        .GetField("DisconnectedItem", BindingFlags.Static | BindingFlags.NonPublic)
        .GetValue(null);
    
        2
  •  25
  •   Charlie    11 年前

    BindingOperations.DisconnectedSource