C# 重写元数据和默认样式之间的差异
在制作一个用作拖放目标的自定义控件时,我需要将C# 重写元数据和默认样式之间的差异,c#,wpf,C#,Wpf,在制作一个用作拖放目标的自定义控件时,我需要将AllowDrop属性设置为true。我最初使用了以下代码,但发现从未触发Drop事件: EditorVisual.cs public class EditorVisual : Control { static EditorVisual() { DefaultStyleKeyProperty.OverrideMetadata(typeof(EditorVisual), new Framework
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
}
}
Themes/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设置为true。但是AllowDrop是一个允许继承标志的框架属性,因此为什么ControlTemplate中的所有控件都将AllowDrop设置为true 现在,在WPF中,您不能覆盖支持inherits标志的框架属性的元数据。当您这样做时,您将终止继承的属性 你有两种可能解决这个问题
静态构造函数不能工作的原因是
AllowDrop
是继承的依赖属性。当您更改EditorVisual
控件的默认值时,它不会将该值向下传播到可视化树,这意味着您提供的模板中的控件仍将AllowDrop
设置为false
。拖放期间的命中测试遇到这些控件并失败
使用样式设置此值(或在控件的实例构造函数中)是完全可以的。您是如何测试此值的?只要看看你的代码,我就知道在代码或xaml中将AllowDrop设置为true是行不通的。顺便说一句,使用OverrideMetadata或Style.Setter并不重要。您将需要重写/写入控件中的其他几个方法,以使拖放工作正常。你能告诉我们这些方法吗?看看这个链接:@devhedgehog,是的,我已经测试过了。虽然您可以覆盖
OnDragEnter
和其他工具来增强体验,但最低要求是AllowDrop=true
和覆盖OnDrop
。请参阅msdn:您是如何测试它的?@devhedgehog,使用visual studio,通过使用调试器运行它。从测试应用程序内以及从explorer
拖动多个对象。无论采用何种方法,事件的OnDrag*
系列都是通过样式设置的AllowDrop
调用的,而不是通过覆盖。