2014-04-15 70 views
1

在我的ScatterView中,我想将&拖放项拖到SurfaceButton上以将它们添加到SurfaceListBox。此时一切正常。Surface ScatterViewItem拖放块缩放

这里是ScatterView我的XAML的代码:

<UserControl x:Class="Ctms.Presentation.Views.ResultView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:p="clr-namespace:Ctms.Presentation.Properties" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:waf="http://waf.codeplex.com/schemas" 
      xmlns:vm="clr-namespace:Ctms.Applications.ViewModels;assembly=Ctms.Applications" 
      xmlns:ps="clr-namespace:PieInTheSky;assembly=PieInTheSky" 
      xmlns:s="http://schemas.microsoft.com/surface/2008" 
      xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
      xmlns:blakenui="clr-namespace:Blake.NUI.WPF.Gestures;assembly=Blake.NUI.WPF" 
      IsEnabled="{Binding IsEnabled}" 
      waf:ValidationHelper.IsValid="{Binding IsValid, Mode=OneWayToSource}"> 


    <Grid> 
     <s:ScatterView Name="MainScatterView" ItemsSource="{Binding Results}" ItemTemplate="{StaticResource ScatterViewItemDataTemplate}" 
        s:SurfaceDragDrop.DragCanceled="Results_OnDragCanceled" 
        s:SurfaceDragDrop.DragCompleted="Results_OnDragCompleted" 
        blakenui:Events.DoubleTapGesture="Results_DoubleTapGesture" 
        PreviewTouchDown="Results_PreviewTouchDown"> 
     </s:ScatterView> 
    </Grid> 
</UserControl> 

这里是我在dragstart

private void Results_PreviewTouchDown(object sender, TouchEventArgs e) 
{ 
    FrameworkElement findSource = e.OriginalSource as FrameworkElement; 
    ScatterViewItem draggedElement = null; 

    // Find the ScatterViewItem object that is being touched. 
    while (draggedElement == null && findSource != null) 
    { 
     if ((draggedElement = findSource as ScatterViewItem) == null) 
     { 
      findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement; 
     } 
    } 

    if (draggedElement == null) 
    { 
     return; 
    } 

    ResultDataModel data = draggedElement.Content as ResultDataModel; 

    // Set the dragged element. This is needed in case the drag operation is canceled. 
    data.DraggedElement = draggedElement; 

    // Create the cursor visual. 
    ContentControl cursorVisual = new ContentControl() 
    { 
     Content = draggedElement.DataContext, 
     Style = FindResource("ResultCursorStyle") as Style 
    }; 

    // Create a list of input devices, 
    // and add the device passed to this event handler. 
    List<InputDevice> devices = new List<InputDevice>(); 
    devices.Add(e.TouchDevice); 

    // If there are touch devices captured within the element, 
    // add them to the list of input devices. 
    foreach (InputDevice device in draggedElement.TouchesCapturedWithin) 
    { 
     if (device != e.TouchDevice) 
     { 
      devices.Add(device); 
     } 
    } 

    // Get the drag source object. 
    ItemsControl dragSource = ItemsControl.ItemsControlFromItemContainer(draggedElement); 

    // Start the drag-and-drop operation. 
    SurfaceDragCursor cursor = 
     SurfaceDragDrop.BeginDragDrop(
     // The ScatterView object that the cursor is dragged out from. 
      dragSource, 
     // The ScatterViewItem object that is dragged from the drag source. 
      draggedElement, 
     // The visual element of the cursor. 
      cursorVisual, 
     // The data attached with the cursor. 
      draggedElement.DataContext, 
     // The input devices that start dragging the cursor. 
      devices, 
     // The allowed drag-and-drop effects of the operation. 
      DragDropEffects.Copy); 

    e.Handled = (cursor != null); 
} 

在资源字典,其中ScatterViewItem-模板放在我还添加了处理程序SizeChanged将监听:

private void ResultWrapper_SizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    FrameworkElement scatterViewItem = e.Source as FrameworkElement; 
    ResultDataModel result = scatterViewItem.DataContext as ResultDataModel; 

    //do some stuff when scaling 
} 

现在,当我禁用DragStart处理程序时,我的SizeChanged处理程序被调用。但是,如果我启用DragStart处理程序,我不能调整ScatterViewItems,导致DragStart立即被调用。

是否有任何解决方案,我可以捕获这两个事件,拖动&下拉以及缩放?

+0

它看起来像你正在使用Windows机制来拖动而不是在功能性内置的scatterViewItem。您的Results_PreviewTouchDown方法将开始拖动,即使ScatterViewItem开始执行某些操作。通过这种方式,触摸将自动附加到DragCursor,而不是让您缩放。我在这里看不到一个简单的解决方案。其实你的SVI你不希望他们移动?只是为了扩展? – Dmitry

+0

我希望他们移动和缩放。但是,当抛弃指定的SurfaceButton时,它们应该应用于SurfaceListBox。 应该如何实现SVI内置的功能?我从这篇文章中获得了拖放代码:[link](http://msdn.microsoft.com/zh-cn/library/ff727736.aspx) – freakimkaefig

回答

1

好吧,那很简单。使用ScatterViewItem.ContainerDeactivated事件。当IsContainerActive切换为false(当容器不再被操纵时)时触发。现在,您只需测试是否在您的某个按钮上。使用ActualCenter属性来知道SVI的放置位置。

编辑:下面是一些代码

我给自己定一个很简单的窗口:

private void ScatterView_ContainerDeactivated(object sender, RoutedEventArgs e) 
{ 
    ScatterViewItem sourceSVI = (ScatterViewItem)e.OriginalSource; 

    //Retrieve Button1 size 
    Rect btn1Bounds = VisualTreeHelper.GetDescendantBounds(btnButton1); 
    //Get the transform between SV and the button1. We need it because ActualCenter is relative to SV. 
    GeneralTransform transform1 = containerScatterView.TransformToVisual(btnButton1); 

    if (btn1Bounds.Contains(transform1.Transform(sourceSVI.ActualCenter))) 
    { 
     //If ActualPoint is in bounds of the button1 then do something 
     Console.WriteLine("Dropped on Button 1"); 
    } 

    //Retrieve Button2 size 
    Rect btn2Bounds = VisualTreeHelper.GetDescendantBounds(btnButton2); 
    //Get the transform between SV and the button1. We need it because ActualCenter is relative to SV. 
    GeneralTransform transform2 = containerScatterView.TransformToVisual(btnButton2); 

    if (btn2Bounds.Contains(transform2.Transform(sourceSVI.ActualCenter))) 
    { 
     //If ActualPoint is in bounds of the button2 then do something else 
     Console.WriteLine("Dropped on Button 2"); 
    } 
} 

我这里使用:

<Grid> 
    <Canvas> 
     <Button x:Name="btnButton1" Canvas.Left="100" Canvas.Top="200" Width="200" Height="200">Button 1</Button> 
     <Button x:Name="btnButton2" Canvas.Left="500" Canvas.Top="300" Width="200" Height="200">Button 2</Button> 
    </Canvas> 

    <s:ScatterView x:Name="containerScatterView" s:ScatterViewItem.ContainerDeactivated="ScatterView_ContainerDeactivated"> 

     <s:ScatterViewItem> 
      <Rectangle Fill="Red" Width="100" Height="100"/> 
     </s:ScatterViewItem> 

     <s:ScatterViewItem> 
      <Rectangle Fill="Green" Width="100" Height="100"/> 
     </s:ScatterViewItem> 

    </s:ScatterView> 
</Grid> 

现在事件处理程序的代码测试点是否在按钮上方的最简单方法。我只是测试点是否在按钮的边界矩形内。也可以使用WPF HitTesting。