2015-09-01 51 views
1

我想启用Drag'n'Drop的一个父控制器,它有一个IsManipulationEnabled = trueWPF Drag&Drop vs操作

当启用操作时,触摸事件不会升级为鼠标事件。为了启用升级,您应该在操作逻辑步骤之前处理触摸事件(请参阅example)。我已经尝试过,它的工作原理......直到我第一次拨打DoDragDrop。然后我不再接收鼠标事件。为什么?

下面是重现此问题的最低代码。为了便于阅读,删除了所有拖放操作。

XAML:

<Window x:Class="Test.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Height="300" Width="300" IsManipulationEnabled="True"> 
    <Grid> 
     <Border Background="Red" 
       x:Name="Border" 
       TouchDown="Border_OnTouchDown" 
       MouseDown="Border_OnMouseDown" 
       TouchUp="Border_OnTouchUp" 
       Width="100" Height="50" /> 
    </Grid> 
</Window> 

C#:

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
    } 

    private void Border_OnTouchDown(object sender, TouchEventArgs e) 
    { 
     Debug.WriteLine("Border_OnTouchDown"); 
     e.Handled = true; 
     e.TouchDevice.Capture((FrameworkElement)sender); 
    } 

    private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     Debug.WriteLine("Border_OnMouseDown!"); 
     DragDrop.DoDragDrop((DependencyObject)sender, "", DragDropEffects.All); 
    } 

    protected override void OnManipulationStarted(ManipulationStartedEventArgs e) 
    { 
     Debug.WriteLine("OnManipulationStarted"); 
     base.OnManipulationStarted(e); 
    } 

    private void Border_OnTouchUp(object sender, TouchEventArgs e) 
    { 
     ((FrameworkElement)sender).ReleaseTouchCapture(e.TouchDevice); 
     e.Handled = true; 
    } 
} 

输出:

Border_OnTouchDown 
Border_OnMouseDown! <- works first time 
Border_OnTouchDown 
Border_OnTouchDown <- no longer works, no matter how many times I tap 
Border_OnTouchDown 
Border_OnTouchDown 
Border_OnTouchDown 
... 

如果我不叫DoDragDropMouseDown - 事件得到提升,因为他们应该。

回答

0

该解决方案适用于任何框架的版本:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Border_OnTouchDown(object sender, TouchEventArgs e) 
    { 
     Debug.WriteLine("Border_OnTouchDown"); 

     IsManipulationEnabled = false; 
     e.TouchDevice.Capture(Border); 
    } 

    private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     Debug.WriteLine("Border_OnMouseDown!"); 
     DragDrop.DoDragDrop((DependencyObject)sender, "", DragDropEffects.All); 
    } 

    protected override void OnManipulationStarted(ManipulationStartedEventArgs e) 
    { 
     Debug.WriteLine("OnManipulationStarted"); 
     base.OnManipulationStarted(e); 
    } 

    private void Border_OnTouchUp(object sender, TouchEventArgs e) 
    { 
     Border.ReleaseTouchCapture(e.TouchDevice); 
     IsManipulationEnabled = true; 
    } 
} 

在这里,我们基本上禁用操作,如果用户触摸的Border。由于拖放操作可能(也可能会)在Border之外结束,因此我们还需要捕获触摸输入以确保接收到TouchUp事件以重新启用操作。

2

看起来像这是在.NET中的错误。我安装了v4.5.2。现在我已经安装了v4.6并且问题不再可重现。

我甚至不需要将项目重定向到v4.6或重新编译它:只需安装新的运行时即可修复所有问题。