最近开发的项目要求做出一个类似于手机中移动图标的效果(android操作系统),就是用鼠标点住一个控件,可以移动这个控件到任意位置,也可以将这个控件拖到一个容器中。完成这个效果需要一个被移动的控件、一个容器控件以及控件的相关事件。下面以Image控件和ListBox控件为例,实现的功能是:在画布中用鼠标按下Image控件,并向任意画布中的位置移动Image控件,同时可以将Image控件移动到ListBox中,拖进ListBox容器控件之后,Image控件只在ListBox容器控件中显示。

代码如下:

///
/// 鼠标是否点住控件
///
bool clicked = false;
///
/// 鼠标的位置
///
Point mousePosition;
///
/// 初始化ListBox控件
///
///
///
private void myListBox_Loaded(object sender, RoutedEventArgs e)
{
//ListBox控件显示的集合 主要是一些对象
ObservableCollection list = new ObservableCollection();
for (int i = files.Length - 1; i >= 0; i--)
{
IconBean iconBean = new IconBean() { IconFileName = "Image/Icon/" + files[i] + ".png", IconText = files[i] };
list.Add(iconBean);
}
myListBox.SelectedIndex = -1;
this.myListBox.ItemsSource = list;
}
///
/// Image控件鼠标按下
///
///
///
private void imageTarget_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null)
{
clicked = true;
//图片放大,显示手形
element.Cursor = Cursors.Hand;
element.Width *= 1.5;
element.Height *= 1.5;
mousePosition = e.GetPosition(null);
element.CaptureMouse();
}

}
///
/// Image控件鼠标弹起
///
///
///
private void imageTarget_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
//判断是否进入了ListBox的区域,进入了ListBox区域的话,新增一个图片到ListBox控件中,并将Image控件隐藏
if (IsInRegions(mousePosition))
{
icons.Add(new IconBean() { IconFileName = "Image/DSCF2684.JPG", IconText = "美女" });
myListBox.ItemsSource = icons;
element.Visibility = Visibility.Collapsed;
}
else//没有进入ListBox的区域,图片大小还原
{
mousePosition.X = mousePosition.Y = 0;
clicked = false;
element.Width /= 1.5;
element.Height /= 1.5;
}
element.ReleaseMouseCapture();
element.Cursor = null;
}
///
/// Image控件移动
///
///
///
private void imageTarget_MouseMove(object sender, MouseEventArgs e)
{
if (clicked)
{
FrameworkElement element = sender as FrameworkElement;
double deltaV = e.GetPosition(null).Y - mousePosition.Y;
double deltaH = e.GetPosition(null).X - mousePosition.X;

double left = deltaH + (double)element.GetValue(Canvas.LeftProperty);
double top = deltaV + (double)element.GetValue(Canvas.TopProperty);
element.SetValue(Canvas.TopProperty, top);//设置Image控件的top属性
element.SetValue(Canvas.LeftProperty, left);//设置Image控件的left属性
mousePosition = e.GetPosition(null);
//判断是否进入了ListBox的区域,如果是:ListBox边框变粗
if (IsInRegions(mousePosition))
{
myListBox.BorderThickness = new Thickness(10);

}
else
{
myListBox.BorderThickness = new Thickness(1);
}
}
}
///
/// 判断鼠标是否有区域内
///
///
private bool IsInRegions(Point p)
{
double x = p.X;
double y = p.Y;
return y > 27 && x < 150;//我的ListBox范围
}

xaml文件的内容:

<UserControl
    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:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    mc:Ignorable="d" xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" x:Class="SilverlightApplication1.MainPage"
    d:DesignWidth="640" d:DesignHeight="480">

    <Canvas Background="White" x:Name="LayoutRoot">
        <Image x:Name="imageTarget" Source="Image/DSCF2684.JPG" Canvas.Left="445.636" Canvas.Top="288.831" Width="96.504" Height="289.513" MouseLeftButtonDown="imageTarget_MouseLeftButtonDown" MouseLeftButtonUp="imageTarget_MouseLeftButtonUp" MouseMove="imageTarget_MouseMove" MouseEnter="imageTarget_MouseEnter" MouseLeave="imageTarget_MouseLeave" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" Canvas.ZIndex="1">
        </Image>
        <TextBlock Text="工具箱" TextWrapping="Wrap" Width="77" HorizontalAlignment="Center" TextAlignment="Center" FontWeight="Bold"/>
        <ListBox Height="453" Width="150" Canvas.Top="27" x:Name="myListBox" Loaded="myListBox_Loaded" MouseEnter="myListBox_MouseEnter" MouseLeftButtonUp="myListBox_MouseLeftButtonUp" MouseLeftButtonDown="myListBox_MouseLeftButtonDown" SelectionChanged="myListBox_SelectionChanged" MouseWheel="myListBox_MouseWheel">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Width="125" Height="90">
                        <Image Source="{Binding IconFileName}" Width="75" Height="75"></Image>
                        <TextBlock Text="{Binding IconText}" TextAlignment="Center" Height="15"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Canvas>
</UserControl>