在制作充当拖放目标的自定义控件时,我需要将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在任何CPU上使用.Net 4.0进行测试 - 调试。
答案 0 :(得分:2)
静态构造函数不起作用的原因是AllowDrop
是继承的依赖项属性。当您更改EditorVisual
控件的默认值时,它不会将值传播到可视树中,这意味着您提供的模板中的控件仍将AllowDrop
设置为false
。拖放期间的命中测试遇到这些控制并失败。
使用样式设置此值(或在控件的实例构造函数中)完全没问题。
答案 1 :(得分:0)
好的我现在明白你是怎么试试的。
事实上,如果你想进行拖放工作,你需要将AllowDrop设置为true。但AllowDrop是一个框架属性,它允许继承标志,因此为什么ControlTemplate中的所有控件都将其AllowDrop设置为true。
现在,事情是在WPF中,您无法覆盖支持继承标志的框架属性的元数据。当你这样做时,你会杀死继承的属性。
你有两种可能性来解决这个问题。
在构造函数中设置值:
public EditorVisual() { this.AllowDrop = true; }
设置样式中的值(这是您已经拥有的)。