c# - OverrideMetadata 和默认样式的区别

标签 c# wpf

在制作充当拖放目标的自定义控件时,我需要将 AllowDrop 属性设置为 true。我最初使用了以下代码,但发现 Drop 事件从未被触发:

EditorVisual.cs

public class EditorVisual : Control
{
    static EditorVisual()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(EditorVisual),
            new FrameworkPropertyMetadata(typeof(EditorVisual)));
        AllowDropProperty.OverrideMetadata(typeof(EditorVisual),
            new FrameworkPropertyMetadata(true));
    }
    // ...
    protected override void OnDrop(DragEventArgs e)
    {
        base.OnDrop(e);
        // this is never called
    }
}

主题/Generic.xaml

<Style TargetType="{x:Type local:EditorVisual}">
    <Setter Property="Background" Value="LightGreen" />
    <!-- Uncomment to make things work -->
    <!-- <Setter Property="AllowDrop" Value="True" /> -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:EditorVisual}">
                <Border Background="{TemplateBinding Background}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>    

最终,我将范围缩小到设置 AllowDrop 属性的方式。在 xaml 或默认样式中设置它可以使一切正常工作......这让我感到困惑。为什么使用元数据覆盖不足以接收自定义控件中的拖/放事件?

编辑:在 Windows 8 上使用 Visual Studio 2012 和 .Net 4.0 在任何 CPU 上进行测试 - 调试。

最佳答案

静态构造函数不起作用的原因是 AllowDrop 是一个继承依赖属性。当您更改 EditorVisual 控件的默认值时,它不会将该值沿可视化树传播,这意味着您提供的模板中的控件仍将 AllowDrop 设置为。拖放过程中的 HitTest 遇到这些控件并失败。

使用样式来设置此值(或在控件的实例构造函数中)是完全可以的。

关于c# - OverrideMetadata 和默认样式的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19073989/

相关文章:

c# - 如何为单个控件覆盖WPF MVVM中的 Material 设计并使用WPF的默认样式

c# - 如何在运行时使用MenuItems动态填充MenuItem?

c# - 设置只读字段(这是错误吗?)

c# - UnitTesting List<T> of custom objects 与 List<S> of custom objects for equality

c# - 关闭任何上下文实例的 EF 更改跟踪

WPF 组合框 - 展平、删除内边框、无 Aero

c# - 如何使用 C# 检测 WPF 中 UI 线程何时启动和停止处理?

c# - 如何创建一个空的 IReadOnlyCollection

c# - BitmapSource 作为图像控件的源

c# - 是否可以使用 Binding.DoNothing 取消 WPF 绑定(bind)到 Control.Template 属性?