c# - 如何在自定义 MarkupExtension 中处理 Freezable?

标签 c# wpf xaml

我有一个工作 custom markup extension它以特定方式从 DataContext 中检索信息(对于这个问题不重要)。

一切都很好,直到我在不属于可视树或逻辑树的元素中使用此标记扩展。在我的特定示例中,元素 InputBindings。在这种情况下,我没有将 FrameworkElement 作为 DependencyObject 进行检索,而是得到了一个 Freezable (KeyBinding)。

如何通过代码访问 DataContext

我的 XAML 代码:

<UserControl.InputBindings>
    <KeyBinding
        Key="CapsLock"
        Command="{wtc:CommandBinding {x:Static b:Commands.OpenTimeLine}}" />
</UserControl.InputBindings>

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

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 );
}

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

AbstractMarkupExtensionAbstractDependencyPropertyBindingExtensionAbstractDataContextBindingExtensionCommandBindingExtension

最佳答案

一种解决方案非常简单。假设您要查找的 DataContext 与根对象的 DataContext 相同,您可以简单地使用 IRootObjectProvider .此提供程序可通过作为 ProvideValue 的参数传递的 IServiceProvider 访问。

var rootProvider = (IRootObjectProvider)ServiceProvider
                       .GetService( typeof( IRootObjectProvider ) );
_frameworkElement = rootProvider.RootObject as FrameworkElement;

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

关于c# - 如何在自定义 MarkupExtension 中处理 Freezable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9036738/

相关文章:

c# - 格式化为两位小数

c# - 变量声明的部分名称

c# - 将具有子实体的实体添加到 Redis 服务器导致 System.StackOverflowException

c# - 无法让 Lamar (IOC) 解决 .NET Core 3.1 中的 API Controller 依赖关系

.net - 使 Windows 应用程序始终位于其他窗口之上并处于焦点位置 - 始终

c# - 无法将类型为 'System.Windows.Application' 的对象转换为类型 'applicationName.App' 错误

wpf - Canvas 的透明模糊的背景

xaml - 实现类似 OnPlatform/OnIdiom 的系统

silverlight - 虚拟化 ListBox 的 ItemsControl 的边距无法正常工作

c# - WPF DataTemplate 绑定(bind)取决于属性的类型