我已经实施了一个小WPF应用程序将动物从商店拖到我的谷仓。 ; - )
我正在使用:
EventToCommand
行为Border
聆听MouseDown
ItemsControl
绑定到ViewModel的ObservableCollection
。它听3个事件:
DragEnter
(将假动物添加到ObservableCollection
以预览动物放置在谷仓的位置)DragLeave
(如果动物未掉落,则移除假动物)Drop
(将动物设置在谷仓中的指定位置)。对不起。我没有上传图片的声誉。所以我尝试了一些ascii arts(尝试将驴拖入谷仓):
Shop | Barn
-------------------------
Mouse | [Mouse] [Dog]
Cat | [.]
Dog | ^
Donkey-|--|
问题在于:
如果我将动物拖入谷仓的指定空间(预览假人):
DragLeave
删除虚拟项目并立即删除DragEnter
将被解雇以重绘虚拟物品。转到第1步。一个inifite循环。闪烁正在运行!
有没有人知道一个不错的小解决方法?
所以这是我的ViewModel的代码:
private string _dummy;
public ObservableCollection<string> Animals { get; private set; }
private void StartDrag(FrameworkElement element)
{
var animal = element.DataContext as string;
if (animal == null) return;
System.Windows.DragDrop.DoDragDrop(element, animal, DragDropEffects.Copy);
}
private void PreviewDrop(DragEventArgs args)
{
if (args.Data.GetDataPresent(typeof (string)))
AddDummy();
}
private void StopDrop(DragEventArgs args)
{
RemoveDummy();
}
private void Drop(DragEventArgs args)
{
var animal = args.Data.GetData(typeof (string)) as string;
if (animal == null) return;
RemoveDummy();
Animals.Add(animal);
}
private void RemoveDummy()
{
if (_dummy == null) return;
Animals.Remove(_dummy);
_dummy = null;
}
private void AddDummy()
{
if (_dummy != null) return;
_dummy = ".";
Animals.Add(_dummy);
}
感谢您的帮助
马塞尔
答案 0 :(得分:3)
好的,我明白了。 IsHitTestVisible
可以解决问题!这是两个解决方案:
第一种方法,快捷方式:
只需将所有动物放入谷仓(通过修改目标ItemTemplate
中的ItemsControl
)至IsHitTestVisible="False"
:
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type system:String}">
<Border Background="Gray" IsHitTestVisible="False">
<TextBlock Text="{Binding}" Foreground="White" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
因此,每个项目仍然可见,但项目和ItemsControl
都没有触发任何事件。可是等等!如果我想通过将新动物拖到旧动物上来取代动物怎么办?我至少需要一个适当的Drop
事件?
第二种方法,更好的方法:
我将IsHitTestVisible="False"
仅设置为虚拟动物(此处我将字符串内容与"."
进行比较,以检查它是否为假人)。
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type system:String}">
<Border Name="AnimalPlace" Background="Gray">
<TextBlock Text="{Binding}" Foreground="White" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value=".">
<Setter TargetName="AnimalPlace" Property="IsHitTestVisible" Value="False" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
最后一种方法适用于MVVM方面,完全符合我的需求。更不用说它可以很容易地适应更复杂的对象(比表示动物的字符串更复杂)。
我现在很开心: - )
答案 1 :(得分:0)
简单的解决方案,您可能只需要使用标志来控制DragLeave
和DragEnter
代码执行。检查Here以了解事件的顺序