2014-04-15 6 views
1

내 ScatterView에서 드롭리스트 아이템을 SurfaceButton으로 드래그하여 SurfaceListBox에 추가하려고합니다. 이 시점에서 모든 것이 잘 작동합니다. 여기 Surface ScatterViewItem 드래그 앤 드롭 블럭 스케일

<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> 

내가도를 추가 ScatterViewItem-템플릿 배치되는 ResourceDictionary에,에서 같은 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); 
} 

내 핸들러 : 여기

는 ScatterView 내 XAML 코드입니다 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-Handler를 비활성화하면 SizeChanged-Handler가 호출됩니다. 그러나 DragStart-Handler를 활성화하면 ScatterViewItems의 크기를 조정할 수 없으므로 DragStart가 즉시 호출됩니다.

두 가지 이벤트를 모두 캡처 할 수있는 솔루션이 있습니까? & 드롭을 끌어서 스케일링 할 수 있습니까?

+0

functionnality로 작성된 scatterViewItem 대신 드래그를 위해 Windows 메커니즘을 사용하는 것처럼 보입니다. Results_PreviewTouchDown 메서드는 ScatterViewItem이 무언가를하기 시작하기 전에 드래그를 시작합니다. 이 방법으로 터치는 DragCursor에 자동으로 연결되어 스케일링을 허용합니다. 나는 여기에 간단한 해결책을 보지 못했다. 사실 SVI는 이동하지 않으려 고합니다. 단지 규모대로? – Dmitry

+0

나는 그들이 움직이고 크기를 조정하기를 원한다. 그러나 지정된 SurfaceButton 위에 떨어 뜨렸을 때 그들은 SurfaceListBox에 적용되어야합니다. SVI 내장 기능을 어떻게 구현해야합니까? 이 기사에서 드래그 앤 드롭 코드를 얻었습니다. [link] (http://msdn.microsoft.com/en-us/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을 사용할 수도 있습니다.