zoukankan      html  css  js  c++  java
  • WPF SurfaceListbox拖拽事件 之一(SurfaceListbox To SurfaceListbox篇)

    效果图:

     

    (1)    DataItem类的用于创建项目SurfaceListBox控制。它有两个属性:

    Name:Item

    CanDrop: 指定的项目是否可以删除目标控制

     
    public class DataItem
        {
            private string name;
            private bool canDrop;
     
            public string Name
            {
                get { return name; }
            }
     
            public bool CanDrop
            {
                get { return canDrop; }
            }
     
            public DataItem(string name, bool canDrop)
            {
                this.name = name;
                this.canDrop = canDrop;
            }
        }

    (2)    DataTemplate对象(数据外衣)指定每个项目的布局,并将Name属性和CanDrop属性的内容两个相应的标签控件。

    <s:SurfaceWindow x:Class="DraggingAndDroppingBetweenSurfaceListBoxes.SurfaceWindow1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:s="http://schemas.microsoft.com/surface/2008"
        Title="DraggingAndDroppingBetweenSurfaceListBoxes"
        >
     
        <s:SurfaceWindow.Resources>
            
            <DataTemplate x:Key="SurfaceListBoxItemDataTemplate">
                <StackPanel Height="120" Width="190" Background="Gray">
                        <Label 
                            Content="{Binding Name}" 
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center"
                            FontSize="20"/>
     
                        <Label 
                            Content="{Binding CanDrop}"
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center"
                            FontSize="18"/>
                    </StackPanel>
            </DataTemplate>
        </s:SurfaceWindow.Resources>
     
        <Grid>
        </Grid>
        
    </s:SurfaceWindow>
     

    (3)    两个ObservableCollection对象来保存数据项定义。这个集合是暴露通过公共属性,定义在后台代码文件为主要SurfaceWindow对象。

    sourceItems: Item数据源列表框

    TargetItems: Item拖放至列表框

    注意:需要引用using System.Collections.ObjectModel;
     
            private ObservableCollection<DataItem> sourceItems;
            private ObservableCollection<DataItem> targetItems;
     
            /// <summary>
            /// Items that bind with the drag source list box.
            /// </summary>
            public ObservableCollection<DataItem> SourceItems
            {
                get
                {
                    if (sourceItems == null)
                    {
                        sourceItems = new ObservableCollection<DataItem>();
                    }
     
                    return sourceItems;
                }
            }
     
            /// <summary>
            /// Items that bind with the drop target list box.
            /// </summary>
            public ObservableCollection<DataItem> TargetItems
            {
                get
                {
                    if (targetItems == null)
                    {
                        targetItems = new ObservableCollection<DataItem>();
                    }
     
                    return targetItems;
                }
            }
     
        }

    (4)     初始化数据(向SourceItem集合中添加DataItem项)

    protected override void OnInitialized(EventArgs e)
            {
                base.OnInitialized(e);
                DataContext = this;
                SourceItems.Add(new DataItem("Hammer", false));
                SourceItems.Add(new DataItem("Saw", true));
                SourceItems.Add(new DataItem("Pliers", true));
                SourceItems.Add(new DataItem("Tape Measure", false));
                SourceItems.Add(new DataItem("Square", true));
                SourceItems.Add(new DataItem("Wrench", false));
                SourceItems.Add(new DataItem("Screwdriver", true));
                SourceItems.Add(new DataItem("Plumb Bob", true));
                SourceItems.Add(new DataItem("Miter Box", false));
                SourceItems.Add(new DataItem("Knife", true));
                SourceItems.Add(new DataItem("Chisel", true));
                SourceItems.Add(new DataItem("Punch", true));
            }

    (5)    创建SurfaceListBox控制和绑定的物品

    DragSource:被拖拽SurfaceListbox集合

    DropTarget:被放置的surfaceListBox集合

    重点是:PreviewTouchDown事件和SurfaceDragDrop的四个事件:DragCompleted,DragEnter,DragLeave,Drop

    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <s:SurfaceListBox 
                Name="DragSource" 
                Grid.Column="0"
                Width="250"
                BorderBrush="{DynamicResource {x:Static s:SurfaceColors.ListBoxItemBackgroundBrushKey}}"
                ItemTemplate="{StaticResource SurfaceListBoxItemDataTemplate}"
                ItemsSource="{Binding Path=SourceItems}"
                PreviewTouchDown="OnDragSourcePreviewTouchDown"
                s:SurfaceDragDrop.DragCompleted="OnDragCompleted"/>
     
            <s:SurfaceListBox 
                Name="DropTarget" 
                Grid.Column="1"
                AllowDrop="True"
                Width="250"
                BorderBrush="{DynamicResource {x:Static s:SurfaceColors.ListBoxItemBackgroundBrushKey}}"
                ItemTemplate="{StaticResource SurfaceListBoxItemDataTemplate}"
                ItemsSource="{Binding Path=TargetItems}"
                s:SurfaceDragDrop.DragEnter="OnDropTargetDragEnter"
                s:SurfaceDragDrop.DragLeave="OnDropTargetDragLeave"
                s:SurfaceDragDrop.Drop="OnDropTargetDrop"/>
        </Grid>

    (6)    CarsorStyle(光标风格设置)目标对象被选中时边框颜色为黄色。拖动目标对象之另外一个surfaceListbox对象中呈现绿色说明可以被放入,呈现红色说明不能不放入。

    <Style x:Key="CursorStyle" TargetType="{x:Type ContentControl}">
                <Setter Property="ContentTemplate" Value="{StaticResource SurfaceListBoxItemDataTemplate}" />
                <Setter Property="BorderThickness" Value="9"/>
                <Setter Property="BorderBrush" Value="{DynamicResource {x:Static s:SurfaceColors.Accent1BrushKey}}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ContentControl}">
                            <Border 
                                BorderThickness="{TemplateBinding BorderThickness}" 
                                BorderBrush="{TemplateBinding BorderBrush}">
                                <ContentPresenter Margin="0"
                                    Content="{TemplateBinding Content}" 
                                    ContentTemplate="{TemplateBinding ContentTemplate}">
                                </ContentPresenter>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="Tag" Value="CanDrop">
                        <Setter Property="BorderBrush" Value="{DynamicResource {x:Static s:SurfaceColors.Accent4BrushKey}}" />
                    </Trigger>
                    <Trigger Property="Tag" Value="CannotDrop">
                        <Setter Property="BorderBrush" Value="{DynamicResource {x:Static s:SurfaceColors.Accent3BrushKey}}" />
                    </Trigger>
                </Style.Triggers>
            </Style>

    (7)    PreviewTouchDown事件

    详细见代码内部文档注释:

    private void OnDragSourcePreviewTouchDown(object sender, TouchEventArgs e)
            {
                   //获取当前触摸对象转换成FrameworkElement
                FrameworkElement findSource = e.OriginalSource as FrameworkElement;
                   //new一个draggedElement初始化为null
                SurfaceListBoxItem draggedElement = null;
     
                // Find the touched SurfaceListBoxItem object.
                while (draggedElement == null && findSource != null)
                {
                    if ((draggedElement = findSource as SurfaceListBoxItem) == null)
                    {
                        findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;
                    }
                }
     
                if (draggedElement == null)
                {
                    return;
                }
     
                // Create the cursor visual.
                ContentControl cursorVisual = new ContentControl()
                {
                    Content = draggedElement.DataContext,
                    Style = FindResource("CursorStyle") as Style
                };
     
                // Add a handler. This will enable the application to change the visual cues.
                SurfaceDragDrop.AddTargetChangedHandler(cursorVisual, OnTargetChanged);
     
                // Create a list of input devices. Add the touches that
                // are currently captured within the dragged element and
                // the current touch (if it isn't already in the list).
                List<InputDevice> devices = new List<InputDevice>();
                devices.Add(e.TouchDevice);
                foreach (TouchDevice touch in draggedElement.TouchesCapturedWithin)
                {
                    if (touch != e.TouchDevice)
                    {
                        devices.Add(touch);
                    }
                }
     
                // Get the drag source object
                ItemsControl dragSource = ItemsControl.ItemsControlFromItemContainer(draggedElement);  
     
                SurfaceDragCursor startDragOkay =
                    SurfaceDragDrop.BeginDragDrop(
                      dragSource,                 // The SurfaceListBox object that the cursor is dragged out from.
                      draggedElement,             // The SurfaceListBoxItem object that is dragged from the drag source.
                      cursorVisual,               // The visual element of the cursor.
                      draggedElement.DataContext, // The data associated with the cursor.
                      devices,                    // The input devices that start dragging the cursor.
                      DragDropEffects.Move);      // The allowed drag-and-drop effects of the operation.
     
                // If the drag began successfully, set e.Handled to true. 
                // Otherwise SurfaceListBoxItem captures the touch 
                // and causes the drag operation to fail.
                e.Handled = (startDragOkay != null);
            }

    (8)    DragEnter事件

    private void OnDropTargetDragEnter(object sender, SurfaceDragDropEventArgs e)
            {
                   //获取DataItem类数据
                DataItem data = e.Cursor.Data as DataItem;
                   //获取CanDrop中的值
                if (!data.CanDrop)
                {
                   //不能被放置到拖动的集合中            
                    e.Effects = DragDropEffects.None;
                }
            }

    (9)    DragLeave事件

    private void OnDropTargetDragLeave(object sender, SurfaceDragDropEventArgs e)
            {
                // Reset the effects.
                e.Effects = e.Cursor.AllowedEffects;
            }

    (10)OnTargetChanged方法(PreviewTouchDown调用了该方法)

    private void OnTargetChanged(object sender, TargetChangedEventArgs e)
            {
                if (e.Cursor.CurrentTarget != null)
                {
                    DataItem data = e.Cursor.Data as DataItem;
                    e.Cursor.Visual.Tag = (data.CanDrop) ? "CanDrop" : "CannotDrop";
                }
                else
                {
                    e.Cursor.Visual.Tag = null;
                }
            }
     

    (11) Drop事件 当一个条目(即允许下降)是掉在目标SurfaceListBox控制,DropEvent事件引发时。事件处理程序添加数据在光标到TargetItems集合,绑定到该控件。

    private void OnDropTargetDrop(object sender, SurfaceDragDropEventArgs e)
            {
                TargetItems.Add(e.Cursor.Data as DataItem);
            }

    (12)DragCompleted事件当目标Item移动到被放置的Listbox中删除原目标元素的Item元素项

     
    private void OnDragCompleted(object sender, SurfaceDragCompletedEventArgs e)
            {
                // If the operation is Move, remove the data from drag source.
                if (e.Cursor.Effects == DragDropEffects.Move)
                {
                    SourceItems.Remove(e.Cursor.Data as DataItem);
                }
            }

    参考链接:http://msdn.microsoft.com/en-us/library/ff727837.aspx

  • 相关阅读:
    laravel windows下安装 gulp 和 laravel-elixir
    php-新特性,生成器的创建和使用
    laravel 使用极验验证码
    laravel 发送邮件
    laravel安装 redis 并驱动 session
    理解HTTP协议(转载)
    iOS中Block的用法,举例,解析与底层原理
    iOS自定义结构体
    dyld环境变量
    iOS中的静态库与动态库,区别、制作和使用
  • 原文地址:https://www.cnblogs.com/DeepBlues/p/2915551.html
Copyright © 2011-2022 走看看