首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理自定义MarkupExtension中的可冻结性?

如何处理自定义MarkupExtension中的可冻结性?
EN

Stack Overflow用户
提问于 2012-01-27 16:33:19
回答 2查看 349关注 0票数 4

我得到了一个工作的自定义标记扩展,它以一种特定的方式从DataContext中检索信息(对于这个问题来说并不重要)。

在不属于可视或逻辑树的元素中使用此标记扩展之前,一切都很顺利。在元素InputBindings中的特定示例中。在这个场景中,我得到了一个FrameworkElement (KeyBinding),而不是以DependencyObject的形式检索一个Freezable

如何通过代码访问 DataContext

我的XAML代码:

代码语言:javascript
运行
复制
<UserControl.InputBindings>
    <KeyBinding
        Key="CapsLock"
        Command="{wtc:CommandBinding {x:Static b:Commands.OpenTimeLine}}" />
</UserControl.InputBindings>

我通常检索DataContext的自定义标记扩展中的代码

代码语言:javascript
运行
复制
protected override object ProvideValue(
    DependencyObject dependencyObject,
    DependencyProperty dependencyProperty )
{
    if ( dependencyObject is Freezable )
    {
        // TODO: How to handle freezable?
    }

    _frameworkElement = dependencyObject as FrameworkElement;
    if ( _frameworkElement == null )
    {
        throw new InvalidImplementationException(
            "The DataContextBinding may only be used on framework elements." );
    }

    if ( !_dataContextChangedHooked )
    {
        _frameworkElement.DataContextChanged += DataContextChanged;
        _dataContextChangedHooked = true;
    }

    return ProvideValue( _frameworkElement.DataContext );
}

整个源代码也是在线的。我有相当广泛的标记扩展类层次结构。

AbstractMarkupExtensionAbstractDependencyPropertyBindingExtensionAbstractDataContextBindingExtension CommandBindingExtension

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-30 13:39:22

一种解决办法令人惊讶地容易。假设您要查找的DataContext与根对象的DataContext相同,您可以简单地使用IRootObjectProvider。此提供程序可通过IServiceProvider访问,后者作为ProvideValue的参数传递。

代码语言:javascript
运行
复制
var rootProvider = (IRootObjectProvider)ServiceProvider
                       .GetService( typeof( IRootObjectProvider ) );
_frameworkElement = rootProvider.RootObject as FrameworkElement;

可能有更复杂的场景,您必须遍历树(通过LogicalChildren)才能找到所需的DataContext

票数 2
EN

Stack Overflow用户

发布于 2012-01-27 16:51:18

这是一种令人讨厌的反思方式:

代码语言:javascript
运行
复制
var context = (FrameworkElement)typeof(DependencyObject)
    .GetProperty("InheritanceContext", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(dependencyObject, null);
var datacontext = context.DataContext;

(对FrameworkElement的强制转换是不安全的,InheritanceContext也是DependencyObject类型的,InheritanceContext通常是声明使用Freezable的属性的对象,如果它不是需要递归的FrameworkElement )

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9036738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档