zoukankan      html  css  js  c++  java
  • 一起谈.NET技术,Silverlight 拖动复制控件 狼人:

      Silverlight 拖动复制控件,就是将控件从一个容器中向另一个容器中拖动时,不是移动控件而把该控件到另一个容器中。这种情形在程序中经常遇到,下面是我做的一个拖动复制控件的示例,仅供有这种需求的朋友们参考。

      新建一个 Silverlight 项目命名为 DragAndCopy ,在新建的项目中添加一个Silverlight 用户控件(Silverlight user control)命名为 DragObject。项目结构如下图所示:Silverlight项目结构

      其中 DragObject 就是要拖动的用户控件,DragObject 的 Xaml 代码如下:

    <UserControl x:Class="DragAndCopy.DragObject"
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable
    ="d"
    d:DesignHeight
    ="300" d:DesignWidth="400">
    <Image x:Name="icon" Width="128" Height="128" Stretch="Fill" />
    </UserControl>

      这里只是演示拖动复制效果,只在 DragObject 中显示一个图标。DragObject 的后置代码如下:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;

    namespace DragAndCopy
    {
    public partial class DragObject : UserControl
    {
    public DragObject()
    {
    InitializeComponent();

    this.Loaded += new RoutedEventHandler(DragObject_Loaded);
    }

    /// <summary>
    /// 唯一标识一个控件
    /// </summary>
    public string UUID
    {
    get;
    set;
    }

    /// <summary>
    /// 鼠标点击的位置
    /// </summary>
    public Point ClickPos
    {
    get;
    set;
    }

    /// <summary>
    /// 图标地址(相对)
    /// </summary>
    public string ImageUri
    {
    get;
    set;
    }

    void DragObject_Loaded(object sender, RoutedEventArgs e)
    {
    if (!string.IsNullOrEmpty(ImageUri))
    {
    BitmapImage bitmap
    = new BitmapImage(new Uri(ImageUri, UriKind.Relative));
    icon.Source
    = bitmap;
    }
    }
    }
    }
      DragObject 的 UUID 属性用来唯一标识一个 DragObject 实例,在鼠标点击 DragObject 时也是通过 UUID 来判断是进行移动还是复制。ClickPos 属性是鼠标点击 DragObject 的位置,ImageUri 属性是 DragObject 的图标的相对地址。

      接下来在 MainPage 中添加几个 DragObject 的实例,并添加一 Canvas 容器。

    <UserControl x:Class="DragAndCopy.MainPage"
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local
    ="clr-namespace:DragAndCopy"
    mc:Ignorable
    ="d"
    d:DesignHeight
    ="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
    <RowDefinition Height="160" />
    <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Border Grid.Row="0" CornerRadius="5,5,5,5" BorderBrush="Green" BorderThickness="1,1,1,1">
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="5,10,5,10">
    <local:DragObject ImageUri="icons/chrome.png"
    Margin
    ="5,5,5,5"
    MouseLeftButtonDown
    ="Handle_MouseLeftButtonDown"
    MouseLeftButtonUp
    ="Handle_MouseLeftButtonUp" />
    <local:DragObject ImageUri="icons/flock.png"
    Margin
    ="5,5,5,5"
    MouseLeftButtonDown
    ="Handle_MouseLeftButtonDown"
    MouseLeftButtonUp
    ="Handle_MouseLeftButtonUp" />
    <local:DragObject ImageUri="icons/galeon.png"
    Margin
    ="5,5,5,5"
    MouseLeftButtonDown
    ="Handle_MouseLeftButtonDown"
    MouseLeftButtonUp
    ="Handle_MouseLeftButtonUp" />
    <local:DragObject ImageUri="icons/ie7.png"
    Margin
    ="5,5,5,5"
    MouseLeftButtonDown
    ="Handle_MouseLeftButtonDown"
    MouseLeftButtonUp
    ="Handle_MouseLeftButtonUp" />
    <local:DragObject ImageUri="icons/konqueror.png"
    Margin
    ="5,5,5,5"
    MouseLeftButtonDown
    ="Handle_MouseLeftButtonDown"
    MouseLeftButtonUp
    ="Handle_MouseLeftButtonUp" />
    <local:DragObject ImageUri="icons/mfirefox.png"
    Margin
    ="5,5,5,5"
    MouseLeftButtonDown
    ="Handle_MouseLeftButtonDown"
    MouseLeftButtonUp
    ="Handle_MouseLeftButtonUp" />
    </StackPanel>
    </Border>

    <Canvas x:Name="rootCanvas" Grid.Row="1" Background="White">

    </Canvas>
    </Grid>
    </UserControl>

      接着实现将 DragObject 从 StackPanel 容器中拖动到 Canvas 容器中时,复制一个 DragObject 到 Canvas 容器。拖动复制这个动作是在 StackPanel 中的 DragObject 上按下鼠标左键,然后将鼠标指针拖动到 Canvas 中后弹起鼠标左键,由此可知 StackPanel 中的 DragObject 需要响应鼠标左键的按下事件,Canvas 需要响应鼠标左键的弹起事件。

      先定义两个变:

    private DragObject curDrag;
    private bool isMouseCaptured;

      curDrag 是用来保存要复制的控件的中间变量,isMouseCaptured 用来判断是否按鼠标左键。

      事件处理代码如下:

    void Handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)?
    {
    DragObject dragObj
    = sender as DragObject;
    if (dragObj != null) // 鼠标左键在 DragObject 上按下
    {
    if (string.IsNullOrEmpty(dragObj.UUID)) // 在控件栏中的 DragObject 上按下
    {
    // 复制要拖动的控件
    curDrag = new DragObject();
    curDrag.UUID
    = Guid.NewGuid().ToString("N"); // 使用 Guid 标识复制的每个控件
    curDrag.ImageUri = dragObj.ImageUri;
    curDrag.ClickPos
    = e.GetPosition(dragObj);
    }
    isMouseCaptured
    = true;
    }
    }
    void Handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    DragObject dragObj
    = sender as DragObject;
    if (sender is Canvas) // 鼠标左键在容器上弹起
    {
    if (isMouseCaptured)
    {
    isMouseCaptured
    = false;
    if (!rootCanvas.Children.Contains(curDrag)) // 复制控件
    {
    double x = e.GetPosition(rootCanvas).X;
    double y = e.GetPosition(rootCanvas).Y;

    rootCanvas.Children.Add(
    new DragObject
    {
    ImageUri
    = curDrag.ImageUri,
    UUID
    = curDrag.UUID,
    ClickPos
    = curDrag.ClickPos
    });

    // 添加控件的鼠标左键按下、弹起事件、设置控件的位置
    DragObject obj = rootCanvas.Children.First(ue => (ue as DragObject).UUID == curDrag.UUID) as DragObject;
    //obj.MouseMove += Handle_MouseMove;
    obj.MouseLeftButtonDown += Handle_MouseLeftButtonDown;

    obj.SetValue(Canvas.TopProperty, y
    - obj.ClickPos.Y);
    obj.SetValue(Canvas.LeftProperty, x
    - obj.ClickPos.X);
    }
    }
    }
    }

      有了以上的代码就可以实现用户控件的复制了。接下实现 Canvas 容器中的控件的拖动事件,拖动控件的是在控件上按下鼠标左键,然后移动鼠标,因此控件需要处理鼠标左键按下和鼠标移动事件。处理代码如下:

    void Handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    DragObject dragObj
    = sender as DragObject;
    if (dragObj != null) // 鼠标左键在 DragObject 上按下
    {
    dragObj.MouseMove
    -= Handle_MouseMove;
    dragObj.MouseMove
    += Handle_MouseMove;

    mouseVerticalPosition
    = e.GetPosition(null).Y;
    mouseHorizontalPosition
    = e.GetPosition(null).X;
    dragObj.CaptureMouse();
    isMouseCaptured
    = true;
    }
    }

      鼠标移动事件处理代码如下:

    void Handle_MouseMove(object sender, MouseEventArgs e)
    {
    DragObject item
    = sender as DragObject;

    if (item != null && isMouseCaptured)
    {
    double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
    double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
    double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
    double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);

    // 设置新位置
    item.SetValue(Canvas.TopProperty, newTop);
    item.SetValue(Canvas.LeftProperty, newLeft);

    // 更新全局变量
    mouseVerticalPosition = e.GetPosition(null).Y;
    mouseHorizontalPosition
    = e.GetPosition(null).X;
    }
    }

      通过以上代码我们实现的拖动复制及移动控件,但是上面的代码还有一些小 Bug, 完整的示例代码请到http://zdd.me/myfiles下载。

  • 相关阅读:
    Java实现 计蒜客 拯救行动
    Java实现 计蒜客 拯救行动
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 173 二叉搜索树迭代器
    Java实现 LeetCode 173 二叉搜索树迭代器
    Visual Studio的SDK配置
    怎样使用CMenu类
    mfc menu用法一
  • 原文地址:https://www.cnblogs.com/waw/p/2162700.html
Copyright © 2011-2022 走看看