覆盖元数据和默认样式之间的区别

本文关键字:之间 区别 样式 默认 元数据 覆盖 | 更新日期: 2023-09-27 18:33:21

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

编辑器可视化.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
    }
}

主题/通用.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 或默认样式中设置它会使一切正常工作......这让我感到困惑。 为什么使用元数据重写不足以接收自定义控件中的拖放事件?

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

覆盖元数据和默认样式之间的区别

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

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

好的,

我现在明白你是如何尝试测试它的。

事实上,如果您希望进行拖放工作,则需要将 AllowDrop 设置为 true。但是 AllowDrop 是一个框架属性,它允许继承标志,因此为什么控件模板中的所有控件也将其 AllowDrop 设置为 true。

现在的事情是在 WPF 中,您无法覆盖支持继承标志的框架属性的元数据。当你这样做时,你会杀死继承的财产。

您有两种可能性可以解决此问题。

  1. 在构造函数中设置值:

    public EditorVisual(){ 这。允许丢弃 = 真;}

  2. 在样式中设置值(这是您已有的值)。