2

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

编辑器Visual.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 上进行测试 - 调试。

4

2 回答 2

2

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

使用样式来设置这个值(或在控件的实例构造函数中)是非常好的。

于 2013-10-01T10:09:53.917 回答
0

好的,我现在了解您如何尝试对其进行测试。

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

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

你有两种可能性来解决这个问题。

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

    公共 EditorVisual() { this.AllowDrop = true; }

  2. 在您的 Style 中设置值(这是您已经拥有的)。

于 2013-10-01T08:37:15.930 回答