2014-04-15 67 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。