<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_forgetu</title><subtitle type="text">好讀書，不求甚解，每有會意，便欣然忘食。</subtitle><id>http://feed.cnblogs.com/blog/u/69546/rss</id><updated>2011-12-24T04:11:41Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/69546/rss"/><entry><id>http://www.cnblogs.com/forgetu/archive/2011/07/23/silverlight-show-hide-datagrid-rowdetail.html</id><title type="text">Silverlight 通过点击按钮显示/隐藏DataGrid的RowDetail</title><summary type="text">Silverlight 中 DataGrid 的 RowDetail 默认显示方式有三种：一、Collapsed 及不显示；二、Visible 及一直显示；三、VisibleWhenSelected 及选中行时显示。有时我们想让用户来选择显示或隐藏某行的详细信息，虽然使用 VisibleWhenSelected 模式会在选中一行时显示相应的详细信息，但是当更改选中行时，之前选中行的详细信息就会隐藏，而且选中一行后也无法隐藏详细信息。（SelectionModel 设置为 Extended ，RowDetailsVisibilityMode 设置为 VisibleWhenSelected ，按住</summary><published>2011-07-22T16:44:00Z</published><updated>2011-07-22T16:44:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/07/23/silverlight-show-hide-datagrid-rowdetail.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/07/23/silverlight-show-hide-datagrid-rowdetail.html"/><content type="html">&lt;p&gt;Silverlight 中 DataGrid 的 RowDetail 默认显示方式有三种：一、Collapsed 及不显示；二、Visible 及一直显示；三、VisibleWhenSelected 及选中行时显示。有时我们想让用户来选择显示或隐藏某行的详细信息，虽然使用 VisibleWhenSelected 模式会在选中一行时显示相应的详细信息，但是当更改选中行时，之前选中行的详细信息就会隐藏，而且选中一行后也无法隐藏详细信息。（SelectionModel 设置为 Extended ，RowDetailsVisibilityMode 设置为 VisibleWhenSelected ，按住 Ctrl 键选中多行时也会同时显示多行的详细信息，但是当松开 Ctrl 键再选择某一行时，其他行的详细信息就会自动隐藏）&lt;/p&gt;&#xD;
&lt;p&gt;下面我将通过一个非常简单的演示如何在 DataGrid 的每一行添加一个按钮，通过点击按钮来显示或隐藏相应行的详细信息。先看一下本示例的运行结果图。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/201107/20110723004328685.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="示例运行结果" border="0" alt="示例运行结果" src="http://images.cnblogs.com/cnblogs_com/forgetu/201107/201107230043304108.png" width="453" height="395" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;一、新建一个 Silverlgiht 项目，命名为 SLDataGridExample 。&lt;/p&gt;&#xD;
&lt;p&gt;二、在项目中添加一个 Person 类，代码如下：&lt;/p&gt;&#xD;
&lt;pre &gt;public class Person : INotifyPropertyChanged&#xD;
{&#xD;
    private string _name;&#xD;
    private int _age;&#xD;
&#xD;
    public string Name&#xD;
    {&#xD;
        get { return _name; }&#xD;
        set&#xD;
        {&#xD;
            _name = value;&#xD;
            NotifyPropertyChanged("Name");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public int Age&#xD;
    {&#xD;
        get { return _age; }&#xD;
        set&#xD;
        {&#xD;
            _age = value;&#xD;
            NotifyPropertyChanged("Age");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public event PropertyChangedEventHandler PropertyChanged;&#xD;
    public void NotifyPropertyChanged(string name)&#xD;
    {&#xD;
        if (PropertyChanged != null)&#xD;
            PropertyChanged(this, new PropertyChangedEventArgs(name));&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;三、在 MainPage.xaml 添加一个 DataGrid 控件，将 DataGrid 的 RowDetailsVisiblityModel 设置为 Collapsed，将 SelectionModel 设置为 Single。DataGrid 的完整代码如下：&lt;/p&gt;&#xD;
&lt;pre &gt;&amp;lt;sdk:DataGrid x:Name="datagrid1" AutoGenerateColumns="False" ItemsSource="{Binding}" RowDetailsVisibilityMode="Collapsed" SelectionMode="Single"&amp;gt;&#xD;
    &amp;lt;sdk:DataGrid.RowDetailsTemplate&amp;gt;&#xD;
        &amp;lt;DataTemplate&amp;gt;&#xD;
            &amp;lt;StackPanel Orientation="Vertical" Background="LightGray"&amp;gt;&#xD;
                &amp;lt;TextBlock Margin="20,10,0,10" Text="{Binding Name}" /&amp;gt;&#xD;
            &amp;lt;/StackPanel&amp;gt;&#xD;
        &amp;lt;/DataTemplate&amp;gt;&#xD;
    &amp;lt;/sdk:DataGrid.RowDetailsTemplate&amp;gt;&#xD;
    &amp;lt;sdk:DataGrid.Columns&amp;gt;&#xD;
        &amp;lt;sdk:DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="140" /&amp;gt;&#xD;
        &amp;lt;sdk:DataGridTextColumn Header="Age" Binding="{Binding Age}" Width="100" /&amp;gt;&#xD;
        &amp;lt;sdk:DataGridTemplateColumn Header="Show/Hide Detail" Width="140"&amp;gt;&#xD;
            &amp;lt;sdk:DataGridTemplateColumn.CellTemplate&amp;gt;&#xD;
                &amp;lt;DataTemplate&amp;gt;&#xD;
                    &amp;lt;Button Content="Show/Hide Detail" Width="120" Click="Button_Click" /&amp;gt;&#xD;
                &amp;lt;/DataTemplate&amp;gt;&#xD;
            &amp;lt;/sdk:DataGridTemplateColumn.CellTemplate&amp;gt;&#xD;
        &amp;lt;/sdk:DataGridTemplateColumn&amp;gt;&#xD;
    &amp;lt;/sdk:DataGrid.Columns&amp;gt;&#xD;
&amp;lt;/sdk:DataGrid&amp;gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;在 DataGrid 的最后一列中添加了一个按钮，DataGrid 的 RowDetailsVisiblityModel 设置为 Collapsed ，我们通过点击这个按钮来显示或隐藏 RowDetail。下面是该按钮的 Click 事件的代码：&lt;/p&gt;&#xD;
&lt;pre &gt;FrameworkElement el = datagrid1.Columns.Last().GetCellContent(datagrid1.SelectedItem);&#xD;
DataGridRow row = DataGridRow.GetRowContainingElement(el.Parent as FrameworkElement);&#xD;
row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;在按钮的 Click 事件中，我们通过当前选中的行获取到当前的 DataGridRow ，然后设置 DataGridRow 的 DetailsVisibility 属性来显示或隐藏当前行的详细信息。然后在代码中添加一些演示用的数据，运行示例，至此通过点击按钮显示或隐藏 RowDetail 效果已经实现，是不是非常简单呢。&lt;img style="border-style: none;"  alt="大笑" src="http://images.cnblogs.com/cnblogs_com/forgetu/201107/201107230043303552.png" /&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;示例代码下载 &lt;a href="https://skydrive.live.com/self.aspx/.Public/SLDataGridExample.7z?cid=cef98e6e6e872161&amp;amp;sc=documents" target="_blank"&gt;SLDataGridExample.7z&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2114538.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/07/23/silverlight-show-hide-datagrid-rowdetail.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-client-side-communication.html</id><title type="text">Silverlight 应用程序之间在客户端通信</title><summary type="text">运行在同一台电脑上的多个 Silverlight 应用程序可以通过本地消息进行通信，通信是在客户端进行的，不需要与服务端交互。使用这一功能可以使在同一页面承载的多个 Silverlight 应用程序之间或不同页面承载的 Silverlight 应用程序之间进行通信，在网页上承载的 Silverlight 应用程序也可以和运行在浏览器外的其他应用程序之间进行通信。要在 Silverlight 应用程序之间的通信，需要建一个信息发送程序和一个信息接收程序，发送端使用 LocalMessageSender 来发送信息，接收端使用 LocalMessageReceiver 来接收信息。信息发送端：创建</summary><published>2011-06-30T15:55:00Z</published><updated>2011-06-30T15:55:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-client-side-communication.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-client-side-communication.html"/><content type="html">&lt;p&gt;运行在同一台电脑上的多个 Silverlight 应用程序可以通过本地消息进行通信，通信是在客户端进行的，不需要与服务端交互。使用这一功能可以使在同一页面承载的多个 Silverlight 应用程序之间或不同页面承载的 Silverlight 应用程序之间进行通信，在网页上承载的 Silverlight 应用程序也可以和运行在浏览器外的其他应用程序之间进行通信。&lt;/p&gt;&#xD;
&lt;p&gt;要在 Silverlight 应用程序之间的通信，需要建一个信息发送程序和一个信息接收程序，发送端使用 LocalMessageSender 来发送信息，接收端使用 LocalMessageReceiver 来接收信息。&lt;/p&gt;&#xD;
&lt;p&gt;信息发送端：&lt;/p&gt;&#xD;
&lt;p&gt;创建发送端时需要提供一个接收端的名称，同时也可以限定接收端所在的域，如果不提供接收端的域默认为 Global 。&lt;/p&gt;&#xD;
&lt;pre &gt;public class MainViewModel : ViewModelBase&#xD;
{&#xD;
    private LocalMessageSender messageSender;&#xD;
    private const int MAXRETRY = 10;&#xD;
    private int retry = 1;&#xD;
&#xD;
    public string SendResult&#xD;
    {&#xD;
        get;&#xD;
        private set;&#xD;
    }&#xD;
&#xD;
    /// &amp;lt;summary&amp;gt;&#xD;
    /// Initializes a new instance of the MainViewModel class.&#xD;
    /// &amp;lt;/summary&amp;gt;&#xD;
    public MainViewModel()&#xD;
    {&#xD;
        SendMessageCommand = new RelayCommand&amp;lt;string&amp;gt;(SendMessage);&#xD;
        messageSender = new LocalMessageSender("receiver1");&#xD;
        messageSender.SendCompleted += new System.EventHandler&amp;lt;SendCompletedEventArgs&amp;gt;(messageSender_SendCompleted);&#xD;
    }&#xD;
&#xD;
    private void messageSender_SendCompleted(object sender, SendCompletedEventArgs e)&#xD;
    {&#xD;
        if (e.Error != null)&#xD;
        {&#xD;
            if (retry &amp;gt; MAXRETRY)&#xD;
            {&#xD;
                SendResult = "Could not send message.";&#xD;
                RaisePropertyChanged("SendResult");&#xD;
                return;&#xD;
            }&#xD;
            else&#xD;
            {&#xD;
                retry++;&#xD;
                SendMessage(e.Message);&#xD;
            }&#xD;
        }&#xD;
        else&#xD;
        {&#xD;
            retry = 1;&#xD;
            SendResult = string.Concat(e.ReceiverName,":", e.Response);&#xD;
            RaisePropertyChanged("SendResult");&#xD;
        }&#xD;
    }&#xD;
        &#xD;
    public RelayCommand&amp;lt;string&amp;gt; SendMessageCommand { get; private set; }&#xD;
    private void SendMessage(string msg)&#xD;
    {&#xD;
        messageSender.SendAsync(msg);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;使用 SendAsync 方法来发送信息，当信息发送成功时引发 SendCompleted 事件，可以通过 SendCompletedEventArgs 的 Response 属性来获取从接收端返回的信息，当信息发送失败时会抛出 SendFailedException ，可以通过 SendCompletedEventArgs 的 Error 属性来获取。&lt;/p&gt;&#xD;
&lt;p&gt;信息接收端：&lt;/p&gt;&#xD;
&lt;p&gt;创建接收端时需要指定接收端的名称，同时也可以限定该名称的范围是限定为全局名称范围还是限定为接收方的特定域和限定接收方可从中接收消息的域。接收端的名称必须在全局范围内唯一，或者在接收端的宿主域内唯一。&lt;/p&gt;&#xD;
&lt;pre &gt;public class MainViewModel : ViewModelBase&#xD;
{&#xD;
    private LocalMessageReceiver messageReceiver;&#xD;
&#xD;
    public string Message&#xD;
    {&#xD;
        get;&#xD;
        private set;&#xD;
    }&#xD;
&#xD;
    /// &amp;lt;summary&amp;gt;&#xD;
    /// Initializes a new instance of the MainViewModel class.&#xD;
    /// &amp;lt;/summary&amp;gt;&#xD;
    public MainViewModel()&#xD;
    {&#xD;
        messageReceiver = new LocalMessageReceiver("receiver1");&#xD;
        messageReceiver.MessageReceived += new System.EventHandler&amp;lt;MessageReceivedEventArgs&amp;gt;(messageReceiver_MessageReceived);&#xD;
        try&#xD;
        {&#xD;
            messageReceiver.Listen();&#xD;
        }&#xD;
        catch (ListenFailedException e)&#xD;
        {&#xD;
            Message = e.Message;&#xD;
            RaisePropertyChanged("Message");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    private void messageReceiver_MessageReceived(object sender, MessageReceivedEventArgs e)&#xD;
    {&#xD;
        e.Response = "Message received.";&#xD;
        Message = e.Message;&#xD;
        RaisePropertyChanged("Message");&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;接收端通过 Listen 方法监听信息，当收到信息时引发 MessageReceived 事件，可以通过 MessageReceivedEventArgs 的 Message 属性来获取接收到的信息，同时可以设置 MessageReceivedEventArgs 的 Response 属性给发送端返回一个信息。&lt;/p&gt;&#xD;
&lt;p&gt;示例代码下载：&lt;a target="_blank" href="https://skydrive.live.com/?cid=cef98e6e6e872161&amp;amp;sc=documents&amp;amp;uc=1&amp;amp;id=CEF98E6E6E872161%21151#"&gt;SLCommunication&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2095129.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-client-side-communication.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-mvvm-childwindow-interaction.html</id><title type="text">Silverlight MVVM 模式下与子窗体交互</title><summary type="text">Model View ViewModel（MVVM）是在 Silverlight 和 WPF 项目开发中应用最多的结构模式，也是 Silverlight 和 WPF 项目开发的最佳模式。本文的主要目的不是讲解 MVVM 模式，如果您不了解 MVVM 模式，可心参看这里和这里。目前已有很多 MVVM 框架可以用来简化 MVVM 开发，如 Prism、SilverlightFX、MvvmLight、Caliburn、Simple MVVM Toolkit等。在程序开发中经常会遇到诸如弹出提示框、确认框、用户输入窗口等的情况，在 Silverlight 中这些情况都可以用子窗体（Child Wind</summary><published>2011-06-29T16:02:00Z</published><updated>2011-06-29T16:02:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-mvvm-childwindow-interaction.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-mvvm-childwindow-interaction.html"/><content type="html">&lt;p&gt;Model View ViewModel（&lt;a target="_blank" href="http://en.wikipedia.org/wiki/Model_View_ViewModel" title="Model View ViewModel architectural pattern"&gt;MVVM&lt;/a&gt;）是在 Silverlight 和 WPF 项目开发中应用最多的结构模式，也是 Silverlight 和 WPF 项目开发的最佳模式。本文的主要目的不是讲解 &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Model_View_ViewModel" title="Model View ViewModel architectural pattern"&gt;MVVM&lt;/a&gt; 模式，如果您不了解 &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Model_View_ViewModel" title="Model View ViewModel architectural pattern"&gt;MVVM&lt;/a&gt; 模式，可心参看&lt;a target="_blank" href="http://www.silverlight.net/learn/tutorials/silverlight-4/using-the-mvvm-pattern-in-silverlight-applications/" title="using the mvvm pattern in silverlight"&gt;这里&lt;/a&gt;和&lt;a target="_blank" href="http://johnpapa.net/5-minute-overview-of-mvvm-in-silverlight" title="5 minute overview of mvvm in silverlight"&gt;这里&lt;/a&gt;。目前已有很多 &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Model_View_ViewModel" title="Model View ViewModel architectural pattern"&gt;MVVM&lt;/a&gt; 框架可以用来简化 MVVM 开发，如 &lt;a target="_blank" href="http://compositewpf.codeplex.com/" title="Prism"&gt;Prism&lt;/a&gt;、&lt;a target="_blank" href="http://projects.nikhilk.net/SilverlightFX" title="SilverlightFX"&gt;SilverlightFX&lt;/a&gt;、&lt;a target="_blank" href="http://www.galasoft.ch/mvvm/" title="MvvmLight"&gt;MvvmLight&lt;/a&gt;、&lt;a target="_blank" href="http://caliburn.codeplex.com/" title="Caliburn"&gt;Caliburn&lt;/a&gt;、&lt;a target="_blank" href="http://simplemvvmtoolkit.codeplex.com/" title="Simple MVVM Toolkit"&gt;Simple MVVM Toolkit&lt;/a&gt;等。&lt;/p&gt;&#xD;
&lt;p&gt;在程序开发中经常会遇到诸如弹出提示框、确认框、用户输入窗口等的情况，在 Silverlight 中这些情况都可以用子窗体（Child Window）来处理。在未使用 MVVM 模式的情况下，我们可以在用户控件或页面的后置代码（Code Behind）中实例化一个子窗体，调用子窗体的 Show 方法来弹出子窗体，然后通过子窗体的 Closed 方法处理用户的操作结果。但是在使用 MVVM 模式的情况下，为了使 Model 和 View 最大限度的分离，我们要使用尽可能少的后置代码。如果在后置代码中实例化并显示子窗体，这就使用代码和视图结合在一起了；当然也可以在 ViewModel 里实例化并显示子窗体，这样又使子窗体和 ViewModel 结合在一起了。&lt;/p&gt;&#xD;
&lt;p&gt;本文将使用 MvvmLight 框架来演示如何在 MVVM 模式下与子窗体交互，即如何在 ViewModel 中弹出一个子窗体并处理用户操作结果。关于 MvvmLight 的下载及安装请看&lt;a target="_blank" href="http://www.galasoft.ch/mvvm/installing/manually/" title="MvvmLight download and install"&gt;这里&lt;/a&gt;。 &lt;/p&gt;&#xD;
&lt;p&gt;首先我们来看一下示例程序的运行结果：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106300001326746.png"&gt;&lt;img height="184" width="244" src="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106300001331795.png" alt="2011-06-29_230145" border="0" title="2011-06-29_230145" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;程序运行后当用户单击 New Customer 按钮时，就会弹出一个子窗体，用户输入Customer Id、Customer Name、Customer City 后单击 OK 按钮就会在主页面的客户列表中显示出刚才输入的客户信息。下面是本示例具体的实现。&lt;/p&gt;&#xD;
&lt;p&gt;新建一个 Silverlight 项目，然后在项目中添加Views、Models、ViewModels、Locators文件夹（如果是通过 MvvmLight 模板创建的 Silverlight 项目，默认 ViewModel Locator 和 ViewModel 在同一文件夹中）。添加对程序集 GalaSoft.MvvmLight.Extras.SL4 和 GalaSoft.MvvmLight.SL4 的引用（如果通过 MvvLight 模板创建则会自动引用）。在 Model 文件夹中新建一个 Customer Model，完整代码如下：&lt;/p&gt;&#xD;
&lt;pre &gt;public class Customer : INotifyPropertyChanged&#xD;
{&#xD;
    private string customerId;&#xD;
    public string CustomerId&#xD;
    {&#xD;
        get { return customerId; }&#xD;
        set&#xD;
        {&#xD;
            customerId = value;&#xD;
            NotifyPropertyChanged("CustomerID");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    private string customerName;&#xD;
    public string CustomerName&#xD;
    {&#xD;
        get { return customerName; }&#xD;
        set&#xD;
        {&#xD;
            customerName = value;&#xD;
            NotifyPropertyChanged("CustomerName");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    private string city;&#xD;
    public string City&#xD;
    {&#xD;
        get { return city; }&#xD;
        set&#xD;
        {&#xD;
            city = value;&#xD;
            NotifyPropertyChanged("City");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public event PropertyChangedEventHandler PropertyChanged;&#xD;
&#xD;
    public void NotifyPropertyChanged(string propertyName)&#xD;
    {&#xD;
        if (PropertyChanged != null)&#xD;
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;下面是 MainPage 的后置代码:&lt;/p&gt;&#xD;
&lt;pre &gt;public partial class MainPage : UserControl&#xD;
{&#xD;
    public MainPage()&#xD;
    {&#xD;
        InitializeComponent();&#xD;
&#xD;
        Messenger.Default.Register&amp;lt;string&amp;gt;(&#xD;
            this,&#xD;
            "MainWindow",&#xD;
            msg =&amp;gt;&#xD;
            {&#xD;
                NewCustomerView newCustomer = new NewCustomerView();&#xD;
                newCustomer.Title = msg;&#xD;
                newCustomer.Show();&#xD;
            });&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;从上面的代码中可以看到，我使用 MvvmLight 的 Messenger 在主窗体中注册了一个消息接收者，用于接收 ViewModel 发来的消息并弹出子窗体。下面是子窗体 NewCustomerView 的后置代码：&lt;/p&gt;&#xD;
&lt;pre &gt;public partial class NewCustomerView : ChildWindow&#xD;
{&#xD;
    public NewCustomerView()&#xD;
    {&#xD;
        InitializeComponent();&#xD;
&#xD;
        Messenger.Default.Register&amp;lt;Customer&amp;gt;(&#xD;
            this,&#xD;
            "ChildWindow",&#xD;
            msg =&amp;gt;&#xD;
            {&#xD;
                this.DialogResult = true;&#xD;
            });&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;我同样在子窗体中也注册一个消息接收者，接收 ViewModel 发来的消息并关闭子窗体。注意主窗体中注册的消息接收者的 Token 为 &amp;ldquo;MainWindow&amp;rdquo;，子窗体中注册的消息接收者的 Token 为 &amp;ldquo;ChildWindow&amp;rdquo;，在 ViewModel 中发送消息时，只有与发送的消息的 Token 相同的接收者才收到消息。下面是 MainViewModel 的代码，这里只是为了演示，主窗体和子窗体共用了一个 ViewModel。&lt;/p&gt;&#xD;
&lt;pre &gt;public class MainViewModel : ViewModelBase&#xD;
{        &#xD;
    public MainViewModel()&#xD;
    {&#xD;
        OKButtonCommand = new RelayCommand&amp;lt;Customer&amp;gt;(OKButtonClick);&#xD;
        NewCustomerCommand = new RelayCommand(NewCustomer);&#xD;
&#xD;
        _customer = new Customer();&#xD;
        _customers = new ObservableCollection&amp;lt;Customer&amp;gt;();&#xD;
        // 注册一个接收者 Token 为 ChildWindow&#xD;
        Messenger.Default.Register&amp;lt;Customer&amp;gt;(this, "ChildWindow", AddCustomer);&#xD;
    }&#xD;
&#xD;
    private void AddCustomer(Customer param)&#xD;
    {&#xD;
        _customers.Add(param);&#xD;
        RaisePropertyChanged("Customers");&#xD;
    }&#xD;
&#xD;
    // customer list&#xD;
    private ObservableCollection&amp;lt;Customer&amp;gt; _customers;&#xD;
    public ObservableCollection&amp;lt;Customer&amp;gt; Customers&#xD;
    {&#xD;
        get&#xD;
        {&#xD;
            return _customers;&#xD;
        }&#xD;
    }&#xD;
&#xD;
    // customer model&#xD;
    private Customer _customer;&#xD;
    public Customer Model&#xD;
    {&#xD;
        get&#xD;
        {&#xD;
            return _customer;&#xD;
        }&#xD;
        set&#xD;
        {&#xD;
            _customer = value;&#xD;
            RaisePropertyChanged("Model");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    // add customer command&#xD;
    public RelayCommand NewCustomerCommand { get; private set; }&#xD;
    private void NewCustomer()&#xD;
    {&#xD;
        /*&#xD;
            * 发送一个字符串信息 New Customer&#xD;
            * Token 为 MainWindow 只有具有相同 Token 接收者都会接收到该信息&#xD;
            */&#xD;
        Messenger.Default.Send("New Customer", "MainWindow");&#xD;
    }&#xD;
&#xD;
    public RelayCommand&amp;lt;Customer&amp;gt; OKButtonCommand { get; private set; }&#xD;
    private void OKButtonClick(Customer param)&#xD;
    {&#xD;
        /*&#xD;
            * 发送一个 Customer 信息&#xD;
            * Token 为 ChildWindow 只有具有相同 Token 接收者都会接收到该信息&#xD;
            */&#xD;
        Messenger.Default.Send&amp;lt;Customer&amp;gt;(param, "ChildWindow");&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;在 ViewModel 中也注册了一个消息接收者，用于接收子窗体返回的数据。ViewModel 中的 NewCustomerCommand 是绑定到主窗体的 NewCustomer 按钮的，单击按钮 NewCustomer 时调用 NewCustomer() 方法向主窗体发送一个消息， 主窗体接收到消息后弹出子窗体。ViewModel 中的 OKButtonCommand 是绑定到子窗体的 OKButton 的，单击按钮 OKButton 时调用 OKButtonClick() 向子窗体和 ViewModel 发送一个消息，子窗体接收到消息时关闭，ViewModel 接收到消息时将参数 Customer 添加 Customer 列表中。以下是按钮的事件绑定代码：&lt;/p&gt;&#xD;
&lt;pre &gt;&amp;lt;Button Content="New Customer" Width="120" Height="30"&amp;gt;&#xD;
    &amp;lt;i:Interaction.Triggers&amp;gt;&#xD;
        &amp;lt;i:EventTrigger EventName="Click"&amp;gt;&#xD;
            &amp;lt;cmd:EventToCommand Command="{Binding NewCustomerCommand}" /&amp;gt;&#xD;
        &amp;lt;/i:EventTrigger&amp;gt;&#xD;
    &amp;lt;/i:Interaction.Triggers&amp;gt;&#xD;
&amp;lt;/Button&amp;gt;&#xD;
&#xD;
&amp;lt;Button x:Name="OkButton" Content="OK" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1"&amp;gt;&#xD;
    &amp;lt;i:Interaction.Triggers&amp;gt;&#xD;
        &amp;lt;i:EventTrigger EventName="Click"&amp;gt;&#xD;
            &amp;lt;cmd:EventToCommand Command="{Binding OKButtonCommand}" CommandParameter="{Binding ElementName=Customer, Path=DataContext}" /&amp;gt;&#xD;
        &amp;lt;/i:EventTrigger&amp;gt;&#xD;
    &amp;lt;/i:Interaction.Triggers&amp;gt;&#xD;
&amp;lt;/Button&amp;gt;&lt;/pre&gt;&#xD;
&lt;p&gt;本示例只是提供一个在 MVVM 模式下与子窗体交互的解决方法，这个解决方法也并不是纯粹的 MVVM，完整的示例请查看附件的示例代码。&lt;/p&gt;&#xD;
&lt;p&gt;示例代码下载：&lt;a target="_blank" href="https://skydrive.live.com/?cid=CEF98E6E6E872161&amp;amp;id=CEF98E6E6E872161%21151#"&gt;SLMvvmChildWindow&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2093896.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/06/30/silverlight-mvvm-childwindow-interaction.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2011/06/18/silverlight-binding-dynamic-object-anonymous-class.html</id><title type="text">Silverlight 通过索引器绑定动态数据</title><summary type="text">绑定动态数据是做 Silverlight 程序时经常会遇到的问题。本文介绍 Silverlight 通过绑定索引器实现绑定动态数据，即在设计时不知道数据的结构，如在设计时不知道要绑定的类有哪些属性。绑定索引器是 Silverlight 4 新增的特性，这一特性使用我们可以在设计时不必知道要绑定的类有哪些属性，但是还可以绑定。下面先看一下如何绑定索引器。&amp;lt;TextBox Grid.Row=&amp;quot;0&amp;quot; Height=&amp;quot;23&amp;quot; Width=&amp;quot;148&amp;quot; HorizontalAlignment=&amp;quot;Center&amp;quot; Verti</summary><published>2011-06-17T16:13:00Z</published><updated>2011-06-17T16:13:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/06/18/silverlight-binding-dynamic-object-anonymous-class.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/06/18/silverlight-binding-dynamic-object-anonymous-class.html"/><content type="html">&lt;p&gt;绑定动态数据是做 Silverlight 程序时经常会遇到的问题。本文介绍 Silverlight 通过绑定索引器实现绑定动态数据，即在设计时不知道数据的结构，如在设计时不知道要绑定的类有哪些属性。&lt;/p&gt;&#xD;
&lt;p&gt;绑定索引器是 Silverlight 4 新增的特性，这一特性使用我们可以在设计时不必知道要绑定的类有哪些属性，但是还可以绑定。下面先看一下如何绑定索引器。&lt;/p&gt;&#xD;
&lt;pre &gt;&amp;lt;TextBox Grid.Row="0" Height="23" Width="148" &#xD;
            HorizontalAlignment="Center" VerticalAlignment="Center" &#xD;
            Name="txtName" Text="&lt;span style="color: #ff0000;" color="#ff0000"&gt;{Binding Path=[name]}&lt;/span&gt;" /&amp;gt;&#xD;
&amp;lt;TextBox Grid.Row="1" Height="23" Width="148" &#xD;
            HorizontalAlignment="Center" VerticalAlignment="Center" &#xD;
            Name="txtAge" Text="&lt;span style="color: #ff0000;" color="#ff0000"&gt;{Binding Path=[age]}&lt;/span&gt;" /&amp;gt;&lt;/pre&gt;&#xD;
&lt;p&gt;绑定索引器的语法和通常绑定数据的语法非常相似，格式为：Binding="{Binding Path=[Key]}" 。下面新建一个要绑定的 Person 类，并添加一个索引器，完整的代码如下：&lt;/p&gt;&#xD;
&lt;pre &gt;public class Person : INotifyPropertyChanged&#xD;
{&#xD;
    private Dictionary&amp;lt;string, object&amp;gt; data = new Dictionary&amp;lt;string, object&amp;gt;();&#xD;
&#xD;
    public object this[string key]&#xD;
    {&#xD;
        get&#xD;
        {&#xD;
            if (!data.ContainsKey(key))&#xD;
                data[key] = null;&#xD;
&#xD;
            return data[key];&#xD;
        }&#xD;
        set&#xD;
        {&#xD;
            data[key] = value;&#xD;
            NotifyPropertyChanged("");&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public string[] Keys&#xD;
    {&#xD;
        get&#xD;
        {&#xD;
            return data.Keys.ToArray();&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public event PropertyChangedEventHandler PropertyChanged;&#xD;
&#xD;
    public void NotifyPropertyChanged(string propertyName)&#xD;
    {&#xD;
        if (PropertyChanged != null)&#xD;
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;下面新建一个 Person 类的实例，并绑定到第一段代码创建的两个TextBox上面。&lt;/p&gt;&#xD;
&lt;pre &gt;Person person = new Person();&#xD;
person["name"] = "avatar";&#xD;
person["age"] = 123456;&#xD;
&#xD;
LayoutRoot.DataContext = person;&lt;/pre&gt;&#xD;
&lt;p&gt;运行结果如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106180013211592.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="未命名" border="0" alt="未命名" src="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106180013219989.jpg" width="200" height="109" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面的代码将索引器的参数名直接写在代码中了，如果在设计时不知道类的结构，上面的代码依然无法解决问题。我们可以通过下面的代码轻松解决这个问题：&lt;/p&gt;&#xD;
&lt;pre &gt;Person person = new Person();&#xD;
person["name"] = "avatar";&#xD;
person["age"] = 123456;&#xD;
&#xD;
LayoutRoot.DataContext = person;&#xD;
&#xD;
for (int i = 0; i &amp;lt; person.Keys.Length; i++)&#xD;
{&#xD;
    TextBox txt = new TextBox()&#xD;
    {&#xD;
        Width = 200,&#xD;
        HorizontalAlignment = HorizontalAlignment.Center,&#xD;
        VerticalAlignment = VerticalAlignment.Center&#xD;
    };&#xD;
    Binding binding = new Binding("[" + person.Keys[i] + "]")&#xD;
    {&#xD;
        Mode = BindingMode.TwoWay&#xD;
    };&#xD;
    txt.SetBinding(TextBox.TextProperty, binding);&#xD;
&#xD;
    txt.SetValue(Grid.RowProperty, i);&#xD;
    LayoutRoot.Children.Add(txt);&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;这段代码的运行结果和上面的代码的运行结果完全一样。&lt;/p&gt;&#xD;
&lt;p&gt;以上讲的是通过索引器将单个类绑定到 Silverlight 控制上，如果要将包含多个类的列表绑定到 DataGrid 上呢？这个问题我们可以通过类似的方式轻松解决。下面是将多个类的列表绑定到 DataGrid 上的代码：&lt;/p&gt;&#xD;
&lt;pre &gt;private List&amp;lt;Person&amp;gt; lst = new List&amp;lt;Person&amp;gt;();&lt;/pre&gt;&#xD;
&lt;pre &gt;Person person1 = new Person();&#xD;
person1["name"] = "Avatar";&#xD;
person1["age"] = 52342;&#xD;
&#xD;
Person person2 = new Person();&#xD;
person2["name"] = "Harry Potter";&#xD;
person2["age"] = 33432;&#xD;
&#xD;
lst.Add(person1);&#xD;
lst.Add(person2);&#xD;
&#xD;
string[] headers = person1.Keys;&#xD;
for (int i = 0; i &amp;lt; headers.Length; i++)&#xD;
{&#xD;
    dataGrid1.Columns.Add(new DataGridTextColumn()&#xD;
    {&#xD;
        Header = headers[i],&#xD;
        CanUserSort = true,&#xD;
        IsReadOnly = false,&#xD;
        Binding = new Binding("[" + headers[i] + "]")&#xD;
        {&#xD;
            Mode = BindingMode.TwoWay&#xD;
        }&#xD;
    });&#xD;
}&#xD;
&#xD;
dataGrid1.ItemsSource = lst;&lt;/pre&gt;&#xD;
&lt;p&gt;注意：如果想让用户可以点击表头排序，需要设置每一列的 CanUserSort = true 。运行结果如下图：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106180013217513.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="未命名" border="0" alt="未命名" src="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106180013221135.jpg" width="244" height="111" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果需要显示 Person 类的性别，只需在上面的代码中添加：person1["gender"] = "男"; person2["gender"] = "男"; 就可以实现，运行结果如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106180013223119.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="未命名" border="0" alt="未命名" src="http://images.cnblogs.com/cnblogs_com/forgetu/201106/201106180013222073.jpg" width="244" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;示例代码下载：&lt;a title="http://cid-cef98e6e6e872161.office.live.com/self.aspx/.Public/SLBindingDynamicObject.7z" href="http://cid-cef98e6e6e872161.office.live.com/self.aspx/.Public/SLBindingDynamicObject.7z"&gt;SLBindingDynamicObject.7z&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2084034.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/06/18/silverlight-binding-dynamic-object-anonymous-class.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2011/05/08/csharp-generics.html</id><title type="text">.NET 中的泛型</title><summary type="text">泛型是 .NET 2.0 中引入的一个新特性，从 .NET 2.0 发布到现在已经过去好多年的时间了，到现在很多公司在面试时都喜欢问诸如用过泛型吗、什么是泛型、怎么写泛型之类的问题。似乎泛型是什么高深莫测的绝学了，犹如辟邪剑法一样，一般人难以运用。其实虽然每个 .NET 程序员的具体工作内容不一样，但是对于 .NET 里的一些基本的东西的运用相差不会很大，我想对于学过C# 的刚毕业的学生也不至于没有用过泛型。下面我就简单说一下泛型。泛型将类型参数的概念引入了 .NET 中，类型参数使类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。使用泛型可以最大限度地重用代码、保护</summary><published>2011-05-08T07:15:00Z</published><updated>2011-05-08T07:15:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/05/08/csharp-generics.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/05/08/csharp-generics.html"/><content type="html">&lt;p&gt;泛型是 .NET 2.0 中引入的一个新特性，从 .NET 2.0 发布到现在已经过去好多年的时间了，到现在很多公司在面试时都喜欢问诸如用过泛型吗、什么是泛型、怎么写泛型之类的问题。似乎泛型是什么高深莫测的绝学了，犹如辟邪剑法一样，一般人难以运用。其实虽然每个 .NET 程序员的具体工作内容不一样，但是对于 .NET 里的一些基本的东西的运用相差不会很大，我想对于学过C# 的刚毕业的学生也不至于没有用过泛型。下面我就简单说一下泛型。&lt;/p&gt;&#xD;
&lt;p&gt;泛型将类型参数的概念引入了 .NET 中，类型参数使类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。使用泛型可以最大限度地重用代码、保护类型的安全以及提高性能。&lt;/p&gt;&#xD;
&lt;p&gt;泛型类型参数&lt;/p&gt;&#xD;
&lt;p&gt;在泛型类或方法的定义中，类型参数是客户端代码在实例化泛型类型的变量时指定的特定类型的占位符。通常我们使用 T 作为类型参数占位符，但这并不是必须的，我们可以使用一些更有意义的描述性的名称作为类型占位符，如 TInput、TOutput 等。&lt;/p&gt;&#xD;
&lt;pre &gt;public class List&amp;lt;TInput, TOutput&amp;gt;&lt;/pre&gt;&#xD;
&lt;p&gt;类型参数的约束&lt;/p&gt;&#xD;
&lt;p&gt;在定义泛型类型时可以对客户端代码在实例化类时用于类型参数的类型加以限制。如果客户端使用违反约束的类型来实例化类型，则会产生编译时错误。约束使用 where 关键字指定。&lt;/p&gt;&#xD;
&lt;table width="675" cellpadding="2" cellspacing="0" border="0"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;结束&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;说明&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;where T: struct&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;类型参数必须是值类型&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;where T: class&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;类型参数必须是引用类型&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;where T: new()&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;类型参数必须有一个 public 且无参数的构造函数 &lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;where T: &amp;lt;base classname&amp;gt;&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;类型参数必须继承至指定的基类（base class）&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;where T: &amp;lt;interface name&amp;gt;&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;类型参数必须是指定的接口或实现了指定接口的类型&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="214" valign="top"&gt;where T: U&lt;/td&gt;&#xD;
&lt;td width="459" valign="top"&gt;为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;pre &gt;public class Student&#xD;
    {&#xD;
        public Student(string name, int age)&#xD;
        {&#xD;
            Name = name;&#xD;
            Age = age;&#xD;
        }&#xD;
        public string Name { get; set; }&#xD;
&#xD;
        public int Age { get; set; }&#xD;
    }&#xD;
&#xD;
    public class Teacher&amp;lt;T&amp;gt; where T : new()&#xD;
    {&#xD;
        public string Name { get; set; }&#xD;
        public int Age { get; set; }&#xD;
        public string Course { get; set; }&#xD;
    }&lt;/pre&gt;&#xD;
&lt;p&gt;上面的代码中我们定义了一个 Student 类和一个 Teacher 类，其中 Student 类只有一个带两个参数的构造函数。Teacher 类是一个泛型类，它的类型参数必须有一个无参的构造函数，如果使用 Student 类去实例化 Teacher 类编辑器会给出错误提示。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/201105/201105081514295569.png"&gt;&lt;img height="124" width="961" src="http://images.cnblogs.com/cnblogs_com/forgetu/201105/20110508151431354.png" alt="2011-05-08_025231" border="0" title="2011-05-08_025231" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;使用约束可以使用我们对泛型成员执行操作时变得更加安全。&lt;/p&gt;&#xD;
&lt;p&gt;泛型类&lt;/p&gt;&#xD;
&lt;p&gt;泛型类封装非特定于具体数据类型的操作。泛型类通常用于集合。像从集合上添加、移除项这样的操作大致相同，且与数据类型无关。对于泛型类可以添加多个约束条件。如我们将上面定义的 Teacher&amp;lt;T&amp;gt; 泛型类的泛型类型参数限制为引用类型。注意在使用多个约束时，如果有 new() 约束，new() 必须放在最后面。&lt;/p&gt;&#xD;
&lt;pre &gt;public class Teacher&amp;lt;T&amp;gt; where T : class, new()&#xD;
    {&#xD;
        public string Name { get; set; }&#xD;
        public int Age { get; set; }&#xD;
        public string Course { get; set; }&#xD;
    }&lt;/pre&gt;&#xD;
&lt;p&gt;泛型接口&lt;/p&gt;&#xD;
&lt;p&gt;为泛型集合或集合中的项的泛型类指定接口通常很有用。将接口指定为泛型类型参数的约束时，只能使用实现该接口的类型。如下面我们为 Teacher&amp;lt;T&amp;gt; 泛型类的类型参数添加必须实现 IComparable&amp;lt;T&amp;gt; 接口限制条件，这样就只有实现了接口 IComparable&amp;lt;T&amp;gt; 且有一个无参的构造函数的引用类型才能作为实例化 Teacher&amp;lt;T&amp;gt; 时的类型参数。&lt;/p&gt;&#xD;
&lt;pre &gt;public class Teacher&amp;lt;T&amp;gt; where T : class, IComparable&amp;lt;T&amp;gt;, new()&#xD;
    {&#xD;
        public string Name { get; set; }&#xD;
        public int Age { get; set; }&#xD;
        public string Course { get; set; }&#xD;
    }&lt;/pre&gt;&#xD;
&lt;br /&gt;泛型方法&#xD;
&lt;p&gt;泛型方法就是使用泛型类型参数声明的方法。如下示例：&lt;/p&gt;&#xD;
&lt;pre &gt;static void Swap&amp;lt;T&amp;gt;(ref T lhs, ref T rhs)&#xD;
{&#xD;
    T temp;&#xD;
    temp = lhs;&#xD;
    lhs = rhs;&#xD;
    rhs = temp;&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;调用泛型方法的方式如下：&lt;/p&gt;&#xD;
&lt;pre &gt;int a = 1;&#xD;
    int b = 2;&#xD;
&#xD;
    Swap&amp;lt;int&amp;gt;(ref a, ref b);&lt;/pre&gt;&#xD;
&lt;p&gt;调用泛型方法时也可以省略泛型类型参数，编译器会根据传入参数的类型推断它的类型。上面的调用方式也可写成这样：&lt;/p&gt;&#xD;
&lt;pre &gt;Swap(ref a, ref b);&lt;/pre&gt;&#xD;
&lt;p&gt;泛型方法也可以通过泛型类型参数重载。&lt;/p&gt;&#xD;
&lt;pre &gt;void DoWork&amp;lt;T&amp;gt;() { }&#xD;
void DoWork&amp;lt;T, U&amp;gt;() { }&lt;/pre&gt;&#xD;
&lt;p&gt;泛型委托&lt;/p&gt;&#xD;
&lt;p&gt;委托也可以定义类型参数，可以像调用泛型类中的泛型方法一样调用泛型委托。例如在 System 命名空间里定义的没有返回值的泛型委托 Action&amp;lt;T&amp;gt;。&lt;/p&gt;&#xD;
&lt;pre &gt;public delegate void Action&amp;lt;in T&amp;gt;(T obj)&lt;/pre&gt;&#xD;
&lt;p&gt;例如 List&amp;lt;T&amp;gt; 的 ForEach( Action&amp;lt;T&amp;gt; action )&amp;nbsp; 的参数是个泛型委托，我们可以传入 Action&amp;lt;T&amp;gt; 泛型委托实例来对列表中的每个元素执行相同的操作。&lt;/p&gt;&#xD;
&lt;pre &gt;[TestMethod]&#xD;
        public void TestMethod1()&#xD;
        {&#xD;
            List&amp;lt;String&amp;gt; names = new List&amp;lt;String&amp;gt;();&#xD;
            names.Add("Bruce");&#xD;
            names.Add("Alfred");&#xD;
            names.Add("Tim");&#xD;
            names.Add("Richard");&#xD;
&#xD;
            names.ForEach(Print);&#xD;
        }&#xD;
&#xD;
        private void Print(string s)&#xD;
        {&#xD;
            Console.WriteLine(s);&#xD;
        }&lt;/pre&gt;&#xD;
&lt;p&gt;使用泛型类型参数时，有一个问题就是由于我们并不知道这个参数是值类型还是引用类型，因此无法设置它的默认值。解决方法是使用 default 关键字，default 关键字对于引用类型会返回null，对于数值类型会返回0，对于结构会返回初始化为0或null的结构成员。&lt;/p&gt;&#xD;
&lt;p&gt;参考：&lt;a href="http://msdn.microsoft.com/en-us/library/512aeb7t(v=VS.100" title="http://msdn.microsoft.com/en-us/library/512aeb7t(v=VS.100)"&gt;http://msdn.microsoft.com/en-us/library/512aeb7t(v=VS.100)&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2040362.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/05/08/csharp-generics.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2011/05/07/dotnet-lazy-initialization.html</id><title type="text">使用 .NET 4.0 中的Lazy&amp;lt;T&amp;gt; 实现延迟初始化</title><summary type="text">延迟初始化就是将对象的初始化延迟到第一次使用该对象时。延迟初始化是我们在写程序时经常会遇到的情形，例如创建某一对象时需要花费很大的开销，而这一对象在系统的运行过程中不一定会用到，这时就可以使用延迟初始化，在第一次使用该对象时再对其进行初始化，使用延迟初始化可以提高程序的效率，使程序占用更少的内存。在 .NET 4.0 之前要实现延迟初始化，需要我们自己动手编写具体的实现方式</summary><published>2011-05-06T16:32:00Z</published><updated>2011-05-06T16:32:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/05/07/dotnet-lazy-initialization.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/05/07/dotnet-lazy-initialization.html"/><content type="html">&lt;p&gt;延迟初始化就是将对象的初始化延迟到第一次使用该对象时。延迟初始化是我们在写程序时经常会遇到的情形，例如创建某一对象时需要花费很大的开销，而这一对象在系统的运行过程中不一定会用到，这时就可以使用延迟初始化，在第一次使用该对象时再对其进行初始化，使用延迟初始化可以提高程序的效率，使程序占用更少的内存。在 .NET 4.0 之前要实现延迟初始化，需要我们自己动手编写具体的实现方式（关于延迟初始化的实现方式，可以参看这个 &lt;a href="http://msdn.microsoft.com/en-us/vcsharp/bb870976.aspx" title="http://msdn.microsoft.com/en-us/vcsharp/bb870976.aspx"&gt;http://msdn.microsoft.com/en-us/vcsharp/bb870976.aspx&lt;/a&gt;&amp;nbsp; .NET 4.0 的 Lazy&amp;lt;T&amp;gt; 的实现方式与此相似）。在 .NET 4.0 中提供了一个泛型类 System.Lazy&amp;lt;T&amp;gt; 可以帮助我们实现延迟初始化。&lt;/p&gt;&#xD;
&lt;p&gt;首先我们来看下面的代码：&lt;/p&gt;&#xD;
&lt;pre &gt;class Program&#xD;
    {&#xD;
        static void Main(string[] args)&#xD;
        {&#xD;
            Lazy&amp;lt;Customer&amp;gt; customer = new Lazy&amp;lt;Customer&amp;gt;();&#xD;
            if (!customer.IsValueCreated)&#xD;
                Console.WriteLine("Customer 尚未初始化。");&#xD;
&#xD;
            Console.WriteLine("客户姓名是：{0}", customer.Value.Name);&#xD;
&#xD;
            if (customer.IsValueCreated)&#xD;
                Console.WriteLine("Customer 已经初始化。");&#xD;
&#xD;
            Console.ReadKey();&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public class Customer&#xD;
    {&#xD;
        public Customer()&#xD;
        {&#xD;
            Name = "张三";&#xD;
            Console.WriteLine("调用 Customer 的构造函数。");&#xD;
        }&#xD;
&#xD;
        public string Name { get; set; }&#xD;
&#xD;
        public List&amp;lt;Order&amp;gt; Orders { get; set; }&#xD;
    }&#xD;
&#xD;
    public class Order&#xD;
    {&#xD;
        public string ID { get; set; }&#xD;
    }&lt;/pre&gt;&#xD;
&lt;p&gt;下面是输出结果:&lt;/p&gt;&#xD;
&lt;p&gt;Customer 尚未初始化。 &#xD;
  &lt;br /&gt;调用 Customer 的构造函数。 &#xD;
  &lt;br /&gt;客户姓名是：张三 &#xD;
  &lt;br /&gt;Customer 已经初始化。&lt;/p&gt;&#xD;
&lt;p&gt;当 customer.Value 被调用时 Customer 才被初始化。只读属性 Value 返回延迟初始化的对象，布尔属性 IsValueCreated 标识延迟初始化的对象是否已经初始化。在上面的示例代码中是在 Customer 类的构造函数中设置的 Name 属性的值，我们可以使用 Lazy&amp;lt;T&amp;gt; 的重载函数 Lazy&amp;lt; T&amp;gt; (Func&amp;lt; T&amp;gt; ) 传入一个带返回值的委托来设置延迟初始化对象的属性值。 &lt;/p&gt;&#xD;
&lt;pre &gt;Lazy&amp;lt;Customer&amp;gt; customer1 = new Lazy&amp;lt;Customer&amp;gt;(&#xD;
            () =&amp;gt;&#xD;
            {&#xD;
                return new Customer { Name = "李四" };&#xD;
            });&lt;/pre&gt;&#xD;
&lt;p&gt;以下是输出结果：&lt;/p&gt;&#xD;
&lt;p&gt;Customer 尚未初始化。 &#xD;
  &lt;br /&gt;调用 Customer 的构造函数。 &#xD;
  &lt;br /&gt;客户姓名是：李四 &#xD;
  &lt;br /&gt;Customer 已经初始化。&lt;/p&gt;&#xD;
&lt;p&gt;可以看到 customer1 的 Value 属性使用的是通过委托传入的参数初始化的。&lt;/p&gt;&#xD;
&lt;p&gt;要实现公共属性的延迟初始化，将属性对应的字段定义为 Lazy&amp;lt;T&amp;gt;，然后通过 get 访问器返回字段的 Value 属性。&lt;/p&gt;&#xD;
&lt;pre &gt;public class Customer&#xD;
    {&#xD;
        public Customer()&#xD;
        {&#xD;
            Name = "张三";&#xD;
            Console.WriteLine("调用 Customer 的构造函数。");&#xD;
&#xD;
            _orders = new Lazy&amp;lt;List&amp;lt;Order&amp;gt;&amp;gt;(() =&amp;gt;&#xD;
                {&#xD;
                    // 初始化&#xD;
                    return new List&amp;lt;Order&amp;gt;&#xD;
                    {&#xD;
                        new Order { ID = "1" },&#xD;
                        new Order { ID = "2" },&#xD;
                        new Order { ID = "3" }&#xD;
                    };&#xD;
                }&#xD;
            );&#xD;
        }&#xD;
&#xD;
        public string Name { get; set; }&#xD;
&#xD;
        private Lazy&amp;lt;List&amp;lt;Order&amp;gt;&amp;gt; _orders;&#xD;
        public List&amp;lt;Order&amp;gt; Orders&#xD;
        {&#xD;
            get&#xD;
            {&#xD;
                return _orders.Value; // 将在第一次访问时创建&#xD;
            }&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public class Order&#xD;
    {&#xD;
        public string ID { get; set; }&#xD;
    }&lt;/pre&gt;&#xD;
&lt;p&gt;Lazy&amp;lt;T&amp;gt; 对象初始化默认是线程安全的，在多线程环境下，第一个访问 Lazy&amp;lt;T&amp;gt; 对象的 Value 属性的线程将初始化 Lazy&amp;lt;T&amp;gt; 对象，以后访问的线程都将使用第一次初始化的数据。&lt;/p&gt;&#xD;
&lt;p&gt;参考：&lt;a href="http://msdn.microsoft.com/en-us/library/dd997286.aspx" title="http://msdn.microsoft.com/en-us/library/dd997286.aspx"&gt;http://msdn.microsoft.com/en-us/library/dd997286.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2039537.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/05/07/dotnet-lazy-initialization.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2011/05/04/csharp-value-and-reference-type.html</id><title type="text">C# 中的值类型和引用类型</title><summary type="text">C# 中所有的数据类型不是值类型就是引用类型。本文就这两种类型在变量定义、赋值、和作为函数参数传递时的不同之外作简单讨论。 值类型是使用对象实际值来表示对象的数据类型。 如果向一个变量分配值类型的实例，则该变量将被赋以该值的全新副本。 引用类型是使用对对象实际值的引用（类似于指针）来表示对象的数据类型。 如果为某个变量分配一个引用类型，则该变量将引用（或指向）原始值。 不创建任何副本。</summary><published>2011-05-04T15:44:00Z</published><updated>2011-05-04T15:44:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2011/05/04/csharp-value-and-reference-type.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2011/05/04/csharp-value-and-reference-type.html"/><content type="html">&lt;p&gt;C# 中所有的数据类型不是值类型就是引用类型。本文就这两种类型在变量定义、赋值、和作为函数参数传递时的不同之外作简单讨论。&lt;/p&gt;&#xD;
&lt;p&gt;值类型是使用对象实际值来表示对象的数据类型。 如果向一个变量分配值类型的实例，则该变量将被赋以该值的全新副本。 &lt;/p&gt;&#xD;
&lt;p&gt;引用类型是使用对对象实际值的引用（类似于指针）来表示对象的数据类型。 如果为某个变量分配一个引用类型，则该变量将引用（或指向）原始值。 不创建任何副本。（来自MSDN）&lt;/p&gt;&#xD;
&lt;p&gt;值类型包括：&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;所有的数值类型 &lt;/li&gt;&#xD;
&lt;li&gt;Boolean、Char 和 DateTime &lt;/li&gt;&#xD;
&lt;li&gt;所有的结构和枚举 &lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;引用类型包括：&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;String &lt;/li&gt;&#xD;
&lt;li&gt;数组 &lt;/li&gt;&#xD;
&lt;li&gt;类、委托和接口 &lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;引用类型和值类型有不同的编译时规则和不同的运行时行为。&lt;/p&gt;&#xD;
&lt;p&gt;对于引用类型，创建对象时，将在堆上分配内存，变量只保存该对象的引用（类似于指针）。如 UriBuilder 是 System 命名空间中定义的一个类，Point 是 System.Drawing 命名空间中定义的一个结构。定义如下变量：&lt;/p&gt;&#xD;
&lt;pre &gt;Point myPoint1 = new Point(20, 10); // Point 是一个结构&#xD;
UriBuilder myUri1 = new UriBuilder("http://www.example.com"); // UriBuilder 是一个类&lt;/pre&gt;&#xD;
&lt;p&gt;在上面的第一行代码中 CLR 将为变量 myPoint1 分配一块内存空间，而在第二行代码中 CLR 将要分配两块内存空间，一块存储 UriBuilder 对象，一块存储该对象的引用（myUri1）。第二行代码等价于：&lt;/p&gt;&#xD;
&lt;pre &gt;UriBuilder myUri1; // CLR 为 UriBuilder 对象的引用 myUri1 分配一块内存空间&#xD;
myUri1 = new UriBuilder("http://www.example.com"); // CLR 为 UriBuilder 对象分配一块内存空间&lt;/pre&gt;&#xD;
&lt;p&gt;如果将上面定义的对象赋值给新的变量:&lt;/p&gt;&#xD;
&lt;pre &gt;Point myPoint2 = myPoint1;&#xD;
UriBuilder myUri2 = myUri1;&lt;/pre&gt;&#xD;
&lt;p&gt;myPoint2 是一个结构，将被赋以 myPoint1 的一个全新的副本。而 myUri2 是一个类，只被赋以对 UriBuilder 对象的引用，myUri1 和 myUri2 都引用同一对象。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;在 C# 中函数的参数默认是按值传递的&lt;/em&gt;&lt;/strong&gt;，即当向函数传递参数时传递的是参数的隐式的副本。对于值类型的参数，传递的是该值的一个副本，对于引用类型的参数，传递的是该引用的一个副本。例如：&lt;/p&gt;&#xD;
&lt;pre &gt;Point point = new Point(20, 5); // 值类型变量&#xD;
UriBuilder myUri = new UriBuilder("http://www.example.com"); // 引用类型变量&#xD;
Test(point, myUri); // Test 为下面定义的一个方法&#xD;
&#xD;
void Test(Point p, UriBuilder uri)&#xD;
{&#xD;
	p.X = 10; // 不会影响 point，因为 p 是 point 的一个副本&#xD;
	uri.Host = "www.example.org"; // 会影响 myUri因为 uri 和 myUri 引用的是同一对象&#xD;
         uri = null; // 不会影响 myUri&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;将 uri 设置为 null 不会产生任何影响，因为 uri 只是 UriBuilder 对象引用的一个副本。&lt;/p&gt;&#xD;
&lt;p&gt;我们可以使用 ref 修饰符改变参数的传递方式，按引用传递时函数直接与调用者的参数交互。例如：&lt;/p&gt;&#xD;
&lt;pre &gt;Point point = new Point(20, 5); // 值类型变量&#xD;
UriBuilder myUri = new UriBuilder("http://www.example.com");// 引用类型变量&#xD;
Test(ref point, ref myUri); // Test 是下面定义的函数&#xD;
&#xD;
void Test(ref Point p, ref UriBuilder uri)&#xD;
{&#xD;
	p.X = 10; // 将会改变 point 的 X 值&#xD;
	uri.Host = "www.example.org"; // 将会改变 myUri 的 Host 值&#xD;
	uri = null; // 将会把 myUri 设置为 null&#xD;
}&lt;/pre&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/2037120.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2011/05/04/csharp-value-and-reference-type.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2010/09/08/silverlight-multiple-select-and-move-control-overflow-check.html</id><title type="text">Silverlight 选择和移动多个控件——移出边界检测和自动将选中的控件全部包含在选择框中</title><summary type="text">在上一篇文章中介绍了 Silverlight 中同时选中和移动多个控件的实现方式，但是并没有对控件是否移出边界进行检测，因此可以把控件拖出容器边界外面，这实际应用中当然是不允许的。还有一点就选中的控件只有选中部分会包含在选择区域中，不会把整个控件都自动包含在选择区域中。以下就上面的两个问题的解决方式做一简单介绍。</summary><published>2010-09-08T14:33:00Z</published><updated>2010-09-08T14:33:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2010/09/08/silverlight-multiple-select-and-move-control-overflow-check.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2010/09/08/silverlight-multiple-select-and-move-control-overflow-check.html"/><content type="html">&lt;p&gt;在&lt;a target="_blank" href="http://zdd.me/cdqjhx"&gt;上一篇文章&lt;/a&gt;中介绍了 Silverlight 中同时选中和移动多个控件的实现方式，但是并没有对控件是否移出边界进行检测，因此可以把控件拖出容器边界外面，这实际应用中当然是不允许的。还有一点就选中的控件只有选中部分会包含在选择区域中，不会把整个控件都自动包含在选择区域中。以下就上面的两个问题的解决方式做一简单介绍。&lt;/p&gt;&#xD;
&lt;p&gt;1、对于第一个问题，只要在移动控件时，对控件移动到的新位置做一个判断就可以，下面是修改后的代码：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;/* rect 的 X 轴值和 Y 轴值  */&#xD;
double rLeft = (double)rect.GetValue(Canvas.LeftProperty);&#xD;
double rTop = (double)rect.GetValue(Canvas.TopProperty);&#xD;
&#xD;
double deltaV = e.GetPosition(rootCanvas).Y - origPoint.Y;&#xD;
double deltaH = e.GetPosition(rootCanvas).X - origPoint.X;&#xD;
double newTop = deltaV + rTop;&#xD;
double newLeft = deltaH + rLeft;&#xD;
&#xD;
if (newTop &amp;lt; 0)  // 已经拖出上侧边缘&#xD;
{&#xD;
	newTop = 0;&#xD;
	deltaV = 0;&#xD;
}&#xD;
else if (newTop &amp;gt; rootCanvas.ActualHeight - rect.ActualHeight)  // 已经拖出下侧边缘&#xD;
{&#xD;
	newTop = rootCanvas.ActualHeight - rect.ActualHeight;&#xD;
	deltaV = newTop - rTop;&#xD;
}&#xD;
if (newLeft &amp;lt; 0)  // 已经拖出左侧边缘&#xD;
{&#xD;
	newLeft = 0;&#xD;
	deltaH = 0;&#xD;
}&#xD;
else if (newLeft &amp;gt; rootCanvas.ActualWidth - rect.ActualWidth)   // 已经拖出右侧边缘&#xD;
{&#xD;
	newLeft = rootCanvas.ActualWidth - rect.ActualWidth;&#xD;
	deltaH = newLeft - rLeft;&#xD;
}&#xD;
&#xD;
foreach (var se in selectedElements)&#xD;
{&#xD;
	double cLeft = deltaH + (double)se.GetValue(Canvas.LeftProperty);&#xD;
	double cTop = deltaV + (double)se.GetValue(Canvas.TopProperty);&#xD;
&#xD;
	se.SetValue(Canvas.LeftProperty, cLeft);&#xD;
	se.SetValue(Canvas.TopProperty, cTop);&#xD;
}&#xD;
&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;/div&gt;&#xD;
&lt;p&gt;注意对下侧边缘的判断要用容器的高减去 rect（选择区域）的高，对于右侧边缘的判断同样要用容器的宽减去 rect 的宽，这是因为通过e.GetPosition(UIElement).X和e.GetPosition(UIElement).Y取得值是 UIElement 的左侧和顶部距容器左侧和顶部的值。&lt;/p&gt;&#xD;
&lt;p&gt;2、对于第二个问题，如果某个控件被选中，只要将该选择区域扩大把控件所在的矩形区域包含在内即可实现（可以通过Rect的Union方法实现），修改后的代码如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;Rect finalRect = Rect.Empty; // 最终要显示的选择区域&#xD;
Rect temp = Rect.Empty;&#xD;
&#xD;
do&#xD;
{&#xD;
	if (finalRect != Rect.Empty)&#xD;
		temp = new Rect(finalRect.X, finalRect.Y, finalRect.Width, finalRect.Height);&#xD;
&#xD;
	foreach (FrameworkElement item in rootCanvas.Children)&#xD;
	{&#xD;
		if (item as Rectangle != null) continue;&#xD;
&#xD;
		double cLeft = (double)item.GetValue(Canvas.LeftProperty);&#xD;
		double cTop = (double)item.GetValue(Canvas.TopProperty);&#xD;
&#xD;
		Rect rc1 = new Rect(selectedRect.X, selectedRect.Y, selectedRect.Width, selectedRect.Height);&#xD;
		Rect rc2 = new Rect(cLeft, cTop, item.ActualWidth, item.ActualHeight);&#xD;
		rc1.Intersect(rc2); /* 判断控件所在的矩形区域与选择的矩形区域是否相交 */&#xD;
		if (rc1 != Rect.Empty)&#xD;
		{&#xD;
			selectedRect.Union(rc2);  /*  扩展 selectedRect 时可能会有新控件包含进选择区域，因此用 do while 循环判断  */&#xD;
			finalRect.Union(rc2);&#xD;
&#xD;
			if (!selectedElements.Contains(item))&#xD;
				selectedElements.Add(item);&#xD;
		}&#xD;
	}&#xD;
} while (temp != finalRect);  /*   如果 temp == finalRect 说明没有新控件选择进来  */&#xD;
&#xD;
if (finalRect != Rect.Empty)&#xD;
{&#xD;
	/*  重新设置选择区域的大小和位置   */&#xD;
	rect.SetValue(Canvas.TopProperty, finalRect.Y);&#xD;
	rect.SetValue(Canvas.LeftProperty, finalRect.X);&#xD;
	rect.SetValue(Rectangle.WidthProperty, finalRect.Width);&#xD;
	rect.SetValue(Rectangle.HeightProperty, finalRect.Height);&#xD;
}&#xD;
&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;同时将上面的代码从鼠标的点击事件中移到了鼠标的弹起事件中，这样在鼠标弹起时就可以自动将选中的控件包含在选择区域内。代码可以到 &lt;a target="_blank" href="http://zdd.me/files"&gt;http://zdd.me/myfiles &lt;/a&gt;下载。&lt;/p&gt;&#xD;
&lt;p&gt;演示地址 &lt;a href="http://v.zdd.me/testpage.html"&gt;http://v.zdd.me/testpage.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/1821809.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2010/09/08/silverlight-multiple-select-and-move-control-overflow-check.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2010/09/04/silverlight-mouse-multiple-select-move-controls.html</id><title type="text">Silverlight 中用鼠标同时选中和移动多个控件</title><summary type="text">在设计 WinForm 程序时，我们可以很方便的同时选择窗体上的多个控件来调整控件的位置。在 Silverlight 应用程序中有时我们也想实现同样的功能，以提供更好的用户体验。本文将要介绍的就是在 Silverlight 程序中实现同时选中和移动多个控件。</summary><published>2010-09-04T02:40:00Z</published><updated>2010-09-04T02:40:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2010/09/04/silverlight-mouse-multiple-select-move-controls.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2010/09/04/silverlight-mouse-multiple-select-move-controls.html"/><content type="html">&lt;p&gt;在设计 WinForm 程序时，我们可以很方便的同时选择窗体上的多个控件来调整控件的位置。在 Silverlight 应用程序中有时我们也想实现同样的功能，以提供更好的用户体验。本文将要介绍的就是在 Silverlight 程序中实现同时选中和移动多个控件。&lt;/p&gt;&#xD;
&lt;p&gt;1、实现鼠标拖动选择时显示所选区域&lt;/p&gt;&#xD;
&lt;p&gt;2、移动所选区域时同时移动在该区域内的控件&lt;/p&gt;&#xD;
&lt;p&gt;要实现鼠标拖动选择时显示所选区域功能，可以在鼠标拖动时在 Canvas 容器中动态添加一个 Rectangle 来显示类似在 Windows 资源管理器拖动选择文件时的选择框。实现前面所述功能的操作：在 Canvas 容器中按下鼠标左键并拖动鼠标来修改选择区域，选定目标区域后松开鼠标按键，这时显示一个表示所选区域的矩形选框。由实现的操作可知，我们需要在鼠标左键按下时在 Canvas 容器中添加一个矩形框，然后在鼠标移动时根据鼠标的位置更新矩形框的大小，最后在鼠标左键弹起显示最终的选择区域并查找出在选择区域中的控件。&lt;/p&gt;&#xD;
&lt;pre &gt;private Point origPoint;  /* 鼠标点击的位置   */&#xD;
private Rectangle rect;   /*  选择的区域  */&#xD;
private Rect selectedRect; /* 选择的矩形区域 */&#xD;
private bool isMultipleSelected;&#xD;
private List&amp;lt;FrameworkElement&amp;gt; selectedElements = new List&amp;lt;FrameworkElement&amp;gt;();&#xD;
&#xD;
public MainPage()&#xD;
{&#xD;
	InitializeComponent();&#xD;
&#xD;
	this.rootCanvas.MouseLeftButtonDown += Handle_MouseLeftButtonDown;&#xD;
}&#xD;
&#xD;
private void Handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)&#xD;
{&#xD;
	if (e.OriginalSource is Canvas)&#xD;
	{&#xD;
		if (rect != null)&#xD;
		{&#xD;
			isMultipleSelected = false;&#xD;
&#xD;
			rootCanvas.Children.Remove(rect);&#xD;
			rect = null;&#xD;
		}&#xD;
		else&#xD;
		{&#xD;
			isMultipleSelected = true;&#xD;
&#xD;
			rect = new Rectangle();&#xD;
			origPoint = e.GetPosition(rootCanvas);&#xD;
&#xD;
			rootCanvas.Children.Add(rect);&#xD;
			rect.SetValue(Canvas.LeftProperty, origPoint.X);&#xD;
			rect.SetValue(Canvas.TopProperty, origPoint.Y);&#xD;
&#xD;
			rect.Fill = new SolidColorBrush(Colors.LightGray);&#xD;
			rect.Stroke = new SolidColorBrush(Colors.Black);&#xD;
			rect.StrokeThickness = 3;&#xD;
			rect.Opacity = .5;&#xD;
&#xD;
			rect.MouseLeftButtonDown += Handle_MouseLeftButtonDown;&#xD;
&#xD;
			rootCanvas.MouseMove += Handle_MouseMove;&#xD;
			rootCanvas.MouseLeftButtonUp += Handle_MouseLeftButtonUp;&#xD;
		}&#xD;
	}&#xD;
	else if (e.OriginalSource is Rectangle)&#xD;
	{&#xD;
		isMultipleSelected = false;&#xD;
&#xD;
		origPoint = e.GetPosition(rootCanvas);&#xD;
&#xD;
		rect.MouseMove += Handle_MouseMove;&#xD;
		rect.MouseLeftButtonUp += Handle_MouseLeftButtonUp;&#xD;
		rect.CaptureMouse();&#xD;
&#xD;
		/*&#xD;
		 * 查找在选择范围内的控件&#xD;
		 * &#xD;
		 */&#xD;
&#xD;
		double rLeft = (double)rect.GetValue(Canvas.LeftProperty);&#xD;
		double rTop = (double)rect.GetValue(Canvas.TopProperty);&#xD;
		&#xD;
		foreach (FrameworkElement item in rootCanvas.Children)&#xD;
		{&#xD;
			double cLeft = (double)item.GetValue(Canvas.LeftProperty);&#xD;
			double cTop = (double)item.GetValue(Canvas.TopProperty);&#xD;
&#xD;
			Rect rc1 = new Rect(selectedRect.X, selectedRect.Y, selectedRect.Width, selectedRect.Height);&#xD;
			Rect rc2 = new Rect(cLeft, cTop, item.ActualWidth, item.ActualHeight);&#xD;
			rc1.Intersect(rc2); /* 判断控件所在的矩形区域与选择的矩形区域是否相交 */&#xD;
			if (rc1 != Rect.Empty)&#xD;
			{&#xD;
				if (!selectedElements.Contains(item))&#xD;
					selectedElements.Add(item);&#xD;
			}&#xD;
		}&#xD;
	}&#xD;
}&#xD;
&#xD;
private void Handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)&#xD;
{&#xD;
	if (isMultipleSelected)&#xD;
	{&#xD;
		/*  所选区域的矩形  */&#xD;
		selectedRect = new Rect((double)rect.GetValue(Canvas.LeftProperty), &#xD;
			(double)rect.GetValue(Canvas.TopProperty), rect.Width, rect.Height);&#xD;
		&#xD;
		rootCanvas.MouseLeftButtonUp -= Handle_MouseLeftButtonUp;&#xD;
		rootCanvas.MouseMove -= Handle_MouseMove;&#xD;
	}&#xD;
}&#xD;
&#xD;
private void Handle_MouseMove(object sender, MouseEventArgs e)&#xD;
{&#xD;
	if (isMultipleSelected)&#xD;
	{&#xD;
		Point curPoint = e.GetPosition(rootCanvas);&#xD;
		if (curPoint.X &amp;gt; origPoint.X)&#xD;
		{&#xD;
			rect.Width = curPoint.X - origPoint.X;&#xD;
		}&#xD;
		if (curPoint.X &amp;lt; origPoint.X)&#xD;
		{&#xD;
			rect.SetValue(Canvas.LeftProperty, curPoint.X);&#xD;
			rect.Width = origPoint.X - curPoint.X;&#xD;
		}&#xD;
		if (curPoint.Y &amp;gt; origPoint.Y)&#xD;
		{&#xD;
			rect.Height = curPoint.Y - origPoint.Y;&#xD;
		}&#xD;
		if (curPoint.Y &amp;lt; origPoint.Y)&#xD;
		{&#xD;
			rect.SetValue(Canvas.TopProperty, curPoint.Y);&#xD;
			rect.Height = origPoint.Y - curPoint.Y;&#xD;
		}&#xD;
	}&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;在上面的代码中首先定义了几个要用到的变量：origPoint 用来保存鼠标点击时的位置，在动态修改矩形选框和移动控件时会用到；rect 显示矩形选框；selectedRect 矩形选框的矩形大小；isMultipleSelected 标识是否是拖动鼠标进行选择；selectedElements 保存在选择区域中的控件。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在鼠标左键单击事件中，先判断是在 Canvas 容器中单击的还是在 Rectangle 中单击的，注意我们是用 e.OriginalSource 来判断引发事件的对象的，因为 Canvas 和 Rectangle 都要处理鼠标左键单击事件，在 Rectangle 上单击时同时会触发 Canvas 上的单击事件，因此用 sender 来判断引发事件的对象是不准确的。如果是在 Canvas 中进行的单击，先判断 rect 变量是否为 null，如果 rect 不为 null 说明之前已进行过选择或单击，则在 Canvas 中移除 rect 并将 rect 设为 null，将 isMultipleSelected 设为 false；如果 rect 为 null，则将 isMultipleSelected 设为 true 表示当前操作是在进行选择，接着新建一个 Rectangle 并记下鼠标点击的位置，然后将新建的 rect 添加到 Canvas 中。如果是在 Rectangle 上进行的单击，则表示已经执行完选择操作了要进行移动选择区域的操作，首先记下鼠标点击的位置并附加相应的处理事件，然后通过遍历 Canvas 的子控件来找出在选择区域的所有控件并保存到selectedElements 中。在判断控件是否在选择区域中时用的是 Rect 的 Intersect （判断两个矩形是否相交） 方法进行判断的，开始想到的是判断控件所在的矩形的四个顶点和选择区域的四个顶点的位置关系，网上打了一下很多人也是这么做的，后来想到 WinForm 中的 Rectangle 中有 Intersect 这个方法，Silverlight 中有没有呢，后来发现 Silverlight 中的 Rectangle 没有 Intersect 这个方法而 Rect 有这个方法，这就是代码中为什么要用 selectedRect 这个变量保存选择区域所在的矩形。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在鼠标左键的弹起事件中，首先判断是不是在进行选择，如果是则记下选择区域所在的矩形。&lt;/p&gt;&#xD;
&lt;p&gt;在鼠标移动事件中，如果是在进行选择，根据鼠标当前所在的位置更新 rect 选择区域的大小。&lt;/p&gt;&#xD;
&lt;p&gt;到这里我们已经完成了建立选择区域的操作，运行结果如下图所示：&lt;a href="http://images.cnblogs.com/cnblogs_com/forgetu/WindowsLiveWriter/Silverlight_233/selectedrectangle_2.png"&gt;&lt;img height="198" width="404" src="http://images.cnblogs.com/cnblogs_com/forgetu/WindowsLiveWriter/Silverlight_233/selectedrectangle_thumb.png" alt="选择区域" border="0" title="选择区域" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" /&gt;&lt;/a&gt;接下来实现移动选择区域时同时对选择的控件进行移动。&lt;/p&gt;&#xD;
&lt;p&gt;实现移动选择区域时现时对选择的控件进行移动的操作是：鼠标在选择区域上按下，接着移动鼠标，在移动鼠标时更新选择区域的位置同时也更新选择的控件的位置。我们需要处理的事件是 Rectangle 的鼠标单击、移动和弹起事件。&lt;/p&gt;&#xD;
&lt;pre &gt;private bool isMouseCaptured;&lt;/pre&gt;&#xD;
&lt;p&gt;首先新建一个 isMouseCaptured 变量，用来标识鼠标是否选中了矩形选框 rect，在 Canvas 的单击事件中将 isMouseCaptured 设为 false，在 Rectangle 的单击事件中将 isMouseCaptured 设为 true 。&lt;/p&gt;&#xD;
&lt;p&gt;选择区域的单击事件的处理代码在上面的代码中已经有了，移动事件和弹起事件的处理代码如下：&lt;/p&gt;&#xD;
&lt;pre &gt;// 鼠标移动事件处理代码  加入Handle_MouseMove中&#xD;
if (isMouseCaptured)&#xD;
{&#xD;
	double deltaV = e.GetPosition(rootCanvas).Y - origPoint.Y;&#xD;
	double deltaH = e.GetPosition(rootCanvas).X - origPoint.X;&#xD;
	double newTop = deltaV + (double)rect.GetValue(Canvas.TopProperty);&#xD;
	double newLeft = deltaH + (double)rect.GetValue(Canvas.LeftProperty);&#xD;
&#xD;
	foreach (var item in selectedElements)&#xD;
	{&#xD;
		double cLeft = (double)item.GetValue(Canvas.LeftProperty);&#xD;
		double cTop = (double)item.GetValue(Canvas.TopProperty);&#xD;
&#xD;
		item.SetValue(Canvas.LeftProperty, deltaH + cLeft);&#xD;
		item.SetValue(Canvas.TopProperty, deltaV + cTop);&#xD;
	}&#xD;
&#xD;
	rect.SetValue(Canvas.TopProperty, newTop);&#xD;
	rect.SetValue(Canvas.LeftProperty, newLeft);&#xD;
&#xD;
	origPoint = e.GetPosition(rootCanvas);&#xD;
}&#xD;
&#xD;
// 鼠标左键弹起事件处理代码 加入Handle_MouseLeftButtonUp中&#xD;
if (isMouseCaptured)&#xD;
{&#xD;
	selectedElements.Clear();&#xD;
	rect.ReleaseMouseCapture();&#xD;
	isMouseCaptured = false;&#xD;
&#xD;
	rootCanvas.Children.Remove(rect);&#xD;
	rect = null;&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;在鼠标移动事件中我们根据鼠标当前的位置更新选择区域的位置和选择的控件的位置，在鼠标左键弹起事件中将记录的选择的控件清除并把选择区域 rect 从 Canvas 容器中移除。&lt;/p&gt;&#xD;
&lt;p&gt;到这里我们已经实现了用鼠标现时选择和移动多个控件的操作。示例代码下载：&lt;a target="_blank" href="http://zdd.me/myfiles"&gt;http://zdd.me/myfiles&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;下面是演示(先用鼠标将上面的图标拖到下面，然后可以用鼠标拖动选择多个移动)：&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;/div&gt;&#xD;
&lt;p style="text-align: left;"&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/1817854.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2010/09/04/silverlight-mouse-multiple-select-move-controls.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/forgetu/archive/2010/08/31/silverlight-drag-as-copy-usercontrol.html</id><title type="text">Silverlight 拖动复制控件</title><summary type="text">Silverlight 拖动复制控件，就是将控件从一个容器中向另一个容器中拖动时，不是移动控件而把该控件到另一个容器中。这种情形在程序中经常遇到，下面是我做的一个拖动复制控件的示例，仅供有这种需求的朋友们参考。</summary><published>2010-08-31T14:48:00Z</published><updated>2010-08-31T14:48:00Z</updated><author><name>forgetu</name><uri>http://www.cnblogs.com/forgetu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/forgetu/archive/2010/08/31/silverlight-drag-as-copy-usercontrol.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/forgetu/archive/2010/08/31/silverlight-drag-as-copy-usercontrol.html"/><content type="html">&lt;p&gt;Silverlight 拖动复制控件，就是将控件从一个容器中向另一个容器中拖动时，不是移动控件而把该控件到另一个容器中。这种情形在程序中经常遇到，下面是我做的一个拖动复制控件的示例，仅供有这种需求的朋友们参考。&lt;/p&gt;&#xD;
&lt;p&gt;新建一个 Silverlight 项目命名为 DragAndCopy ，在新建的项目中添加一个Silverlight 用户控件（Silverlight user control）命名为 DragObject。项目结构如下图所示：&lt;a href="http://blog.designbased.net/wp-content/uploads/2010/08/solution.png"&gt;&lt;img height="263" width="353" src="http://blog.designbased.net/wp-content/uploads/2010/08/solution.png" alt="Silverlight项目结构" title="Silverlight项目结构"  /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;其中 DragObject 就是要拖动的用户控件，DragObject 的 Xaml 代码如下： &lt;/p&gt;&#xD;
&lt;div  id="highlighter_584663"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;UserControl x:Class="DragAndCopy.DragObject"&#xD;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&#xD;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&#xD;
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&#xD;
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&#xD;
    mc:Ignorable="d"&#xD;
    d:DesignHeight="300" d:DesignWidth="400"&amp;gt;&#xD;
    &amp;lt;Image x:Name="icon" Width="128" Height="128" Stretch="Fill" /&amp;gt;&#xD;
&amp;lt;/UserControl&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这里只是演示拖动复制效果，只在&amp;nbsp;DragObject 中显示一个图标。DragObject 的后置代码如下： &lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;using System;&#xD;
using System.Windows;&#xD;
using System.Windows.Controls;&#xD;
using System.Windows.Media.Imaging;&#xD;
&#xD;
namespace DragAndCopy&#xD;
{&#xD;
    public partial class DragObject : UserControl&#xD;
    {&#xD;
        public DragObject()&#xD;
        {&#xD;
            InitializeComponent();&#xD;
&#xD;
            this.Loaded += new RoutedEventHandler(DragObject_Loaded);&#xD;
        }&#xD;
&#xD;
        /// &amp;lt;summary&amp;gt;&#xD;
        /// 唯一标识一个控件&#xD;
        /// &amp;lt;/summary&amp;gt;&#xD;
        public string UUID&#xD;
        {&#xD;
            get;&#xD;
            set;&#xD;
        }&#xD;
&#xD;
        /// &amp;lt;summary&amp;gt;&#xD;
        /// 鼠标点击的位置&#xD;
        /// &amp;lt;/summary&amp;gt;&#xD;
        public Point ClickPos&#xD;
        {&#xD;
            get;&#xD;
            set;&#xD;
        }&#xD;
&#xD;
        /// &amp;lt;summary&amp;gt;&#xD;
        /// 图标地址（相对）&#xD;
        /// &amp;lt;/summary&amp;gt;&#xD;
        public string ImageUri&#xD;
        {&#xD;
            get;&#xD;
            set;&#xD;
        }&#xD;
&#xD;
        void DragObject_Loaded(object sender, RoutedEventArgs e)&#xD;
        {&#xD;
            if (!string.IsNullOrEmpty(ImageUri))&#xD;
            {&#xD;
                BitmapImage bitmap = new BitmapImage(new Uri(ImageUri, UriKind.Relative));&#xD;
                icon.Source = bitmap;&#xD;
            }&#xD;
        }&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div  id="highlighter_903862"&gt;&#xD;
&lt;div &gt;DragObject 的 UUID 属性用来唯一标识一个 DragObject 实例，在鼠标点击 DragObject 时也是通过 UUID 来判断是进行移动还是复制。ClickPos 属性是鼠标点击 DragObject 的位置，ImageUri 属性是 DragObject 的图标的相对地址。&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;接下来在 MainPage 中添加几个 DragObject 的实例，并添加一 Canvas 容器。 &lt;/p&gt;&#xD;
&lt;div  id="highlighter_126872"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;UserControl x:Class="DragAndCopy.MainPage"&#xD;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&#xD;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&#xD;
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&#xD;
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&#xD;
    xmlns:local="clr-namespace:DragAndCopy"&#xD;
    mc:Ignorable="d"&#xD;
    d:DesignHeight="300" d:DesignWidth="400"&amp;gt;&#xD;
    &amp;lt;Grid x:Name="LayoutRoot" Background="White"&amp;gt;&#xD;
        &amp;lt;Grid.RowDefinitions&amp;gt;&#xD;
            &amp;lt;RowDefinition Height="160" /&amp;gt;&#xD;
            &amp;lt;RowDefinition Height="*" /&amp;gt;&#xD;
        &amp;lt;/Grid.RowDefinitions&amp;gt;&#xD;
        &amp;lt;Border Grid.Row="0" CornerRadius="5,5,5,5" BorderBrush="Green" BorderThickness="1,1,1,1"&amp;gt;&#xD;
            &amp;lt;StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="5,10,5,10"&amp;gt;&#xD;
                &amp;lt;local:DragObject ImageUri="icons/chrome.png" &#xD;
                              Margin="5,5,5,5" &#xD;
                              MouseLeftButtonDown="Handle_MouseLeftButtonDown" &#xD;
                              MouseLeftButtonUp="Handle_MouseLeftButtonUp" /&amp;gt;&#xD;
                &amp;lt;local:DragObject ImageUri="icons/flock.png" &#xD;
                              Margin="5,5,5,5" &#xD;
                              MouseLeftButtonDown="Handle_MouseLeftButtonDown"&#xD;
                              MouseLeftButtonUp="Handle_MouseLeftButtonUp" /&amp;gt;&#xD;
                &amp;lt;local:DragObject ImageUri="icons/galeon.png" &#xD;
                              Margin="5,5,5,5" &#xD;
                              MouseLeftButtonDown="Handle_MouseLeftButtonDown" &#xD;
                              MouseLeftButtonUp="Handle_MouseLeftButtonUp" /&amp;gt;&#xD;
                &amp;lt;local:DragObject ImageUri="icons/ie7.png" &#xD;
                              Margin="5,5,5,5" &#xD;
                              MouseLeftButtonDown="Handle_MouseLeftButtonDown" &#xD;
                              MouseLeftButtonUp="Handle_MouseLeftButtonUp" /&amp;gt;&#xD;
                &amp;lt;local:DragObject ImageUri="icons/konqueror.png" &#xD;
                              Margin="5,5,5,5" &#xD;
                              MouseLeftButtonDown="Handle_MouseLeftButtonDown" &#xD;
                              MouseLeftButtonUp="Handle_MouseLeftButtonUp" /&amp;gt;&#xD;
                &amp;lt;local:DragObject ImageUri="icons/mfirefox.png" &#xD;
                              Margin="5,5,5,5" &#xD;
                              MouseLeftButtonDown="Handle_MouseLeftButtonDown" &#xD;
                              MouseLeftButtonUp="Handle_MouseLeftButtonUp" /&amp;gt;&#xD;
            &amp;lt;/StackPanel&amp;gt;&#xD;
        &amp;lt;/Border&amp;gt;&#xD;
&#xD;
        &amp;lt;Canvas x:Name="rootCanvas" Grid.Row="1" Background="White"&amp;gt;&#xD;
            &#xD;
        &amp;lt;/Canvas&amp;gt;&#xD;
    &amp;lt;/Grid&amp;gt;&#xD;
&amp;lt;/UserControl&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;接着实现将 DragObject 从 StackPanel 容器中拖动到 Canvas 容器中时，复制一个 DragObject 到 Canvas 容器。拖动复制这个动作是在 StackPanel 中的 DragObject 上按下鼠标左键，然后将鼠标指针拖动到 Canvas 中后弹起鼠标左键，由此可知 StackPanel 中的 DragObject 需要响应鼠标左键的按下事件，Canvas 需要响应鼠标左键的弹起事件。&lt;/p&gt;&#xD;
&lt;p&gt;先定义两个变量 &lt;/p&gt;&#xD;
&lt;div  id="highlighter_240708"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&lt;a highlighterid="highlighter_240708" commandname="viewSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#viewSource" title="view plain"  style="width: 16px; height: 16px;"&gt;view plain&lt;/a&gt;&#xD;
&lt;div &gt;&#xD;
&lt;object height="16" width="16" type="application/x-shockwave-flash" id="highlighter_240708_clipboard"&gt;&#xD;
&lt;param name="Movie" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="Src" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="WMode" value="Transparent" /&gt;&lt;param name="Play" value="-1" /&gt;&lt;param name="Loop" value="-1" /&gt;&lt;param name="Quality" value="High" /&gt;&lt;param name="Menu" value="0" /&gt;&lt;param name="AllowScriptAccess" value="always" /&gt;&lt;param name="Scale" value="ShowAll" /&gt;&lt;param name="DeviceFont" value="0" /&gt;&lt;param name="EmbedMovie" value="0" /&gt;&lt;param name="SeamlessTabbing" value="1" /&gt;&lt;param name="Profile" value="0" /&gt;&lt;param name="ProfilePort" value="0" /&gt;&lt;param name="AllowNetworking" value="all" /&gt;&lt;param name="AllowFullScreen" value="false" /&gt;&lt;/object&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;a highlighterid="highlighter_240708" commandname="printSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#printSource" title="print"  style="width: 16px; height: 16px;"&gt;print&lt;/a&gt;&lt;a highlighterid="highlighter_240708" commandname="about" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#about" title="?"  style="width: 16px; height: 16px;"&gt;?&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&lt;code &gt;private&lt;/code&gt; &lt;code &gt;DragObject curDrag; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&lt;code &gt;private&lt;/code&gt; &lt;code &gt;bool&lt;/code&gt; &lt;code &gt;isMouseCaptured;&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;curDrag 是用来保存要复制的控件的中间变量，isMouseCaptured 用来判断是否按鼠标左键。&lt;/p&gt;&#xD;
&lt;p&gt;事件处理代码如下： &lt;/p&gt;&#xD;
&lt;div  id="highlighter_717444"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&lt;a highlighterid="highlighter_717444" commandname="viewSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#viewSource" title="view plain"  style="width: 16px; height: 16px;"&gt;view plain&lt;/a&gt;&#xD;
&lt;div &gt;&#xD;
&lt;object height="16" width="16" type="application/x-shockwave-flash" id="highlighter_717444_clipboard"&gt;&#xD;
&lt;param name="Movie" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="Src" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="WMode" value="Transparent" /&gt;&lt;param name="Play" value="0" /&gt;&lt;param name="Loop" value="-1" /&gt;&lt;param name="Quality" value="High" /&gt;&lt;param name="Menu" value="0" /&gt;&lt;param name="AllowScriptAccess" value="always" /&gt;&lt;param name="Scale" value="ShowAll" /&gt;&lt;param name="DeviceFont" value="0" /&gt;&lt;param name="EmbedMovie" value="0" /&gt;&lt;param name="SeamlessTabbing" value="1" /&gt;&lt;param name="Profile" value="0" /&gt;&lt;param name="ProfilePort" value="0" /&gt;&lt;param name="AllowNetworking" value="all" /&gt;&lt;param name="AllowFullScreen" value="false" /&gt;&lt;/object&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;a highlighterid="highlighter_717444" commandname="printSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#printSource" title="print"  style="width: 16px; height: 16px;"&gt;print&lt;/a&gt;&lt;a highlighterid="highlighter_717444" commandname="about" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#about" title="?"  style="width: 16px; height: 16px;"&gt;?&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;01&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;void&lt;/code&gt; &lt;code &gt;Handle_MouseLeftButtonDown(&lt;/code&gt;&lt;code &gt;object&lt;/code&gt; &lt;code &gt;sender, MouseButtonEventArgs e)� &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;02&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;03&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;DragObject dragObj = sender &lt;/code&gt;&lt;code &gt;as&lt;/code&gt; &lt;code &gt;DragObject; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;04&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(dragObj != &lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;)&amp;nbsp; &lt;/code&gt;&lt;code &gt;// 鼠标左键在 DragObject 上按下 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;05&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;06&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(&lt;/code&gt;&lt;code &gt;string&lt;/code&gt;&lt;code &gt;.IsNullOrEmpty(dragObj.UUID)) &lt;/code&gt;&lt;code &gt;// 在控件栏中的 DragObject 上按下 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;07&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;08&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;// 复制要拖动的控件 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;09&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;curDrag = &lt;/code&gt;&lt;code &gt;new&lt;/code&gt; &lt;code &gt;DragObject(); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;curDrag.UUID = Guid.NewGuid().ToString(&lt;/code&gt;&lt;code &gt;"N"&lt;/code&gt;&lt;code &gt;); &lt;/code&gt;&lt;code &gt;// 使用 Guid 标识复制的每个控件 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;11&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;curDrag.ImageUri = dragObj.ImageUri; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;12&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;curDrag.ClickPos = e.GetPosition(dragObj); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;13&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;isMouseCaptured = &lt;/code&gt;&lt;code &gt;true&lt;/code&gt;&lt;code &gt;; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;15&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;16&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;}&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div  id="highlighter_431587"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&lt;a highlighterid="highlighter_431587" commandname="viewSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#viewSource" title="view plain"  style="width: 16px; height: 16px;"&gt;view plain&lt;/a&gt;&#xD;
&lt;div &gt;&#xD;
&lt;object height="16" width="16" type="application/x-shockwave-flash" id="highlighter_431587_clipboard"&gt;&#xD;
&lt;param name="Movie" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="Src" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="WMode" value="Transparent" /&gt;&lt;param name="Play" value="0" /&gt;&lt;param name="Loop" value="-1" /&gt;&lt;param name="Quality" value="High" /&gt;&lt;param name="Menu" value="0" /&gt;&lt;param name="AllowScriptAccess" value="always" /&gt;&lt;param name="Scale" value="ShowAll" /&gt;&lt;param name="DeviceFont" value="0" /&gt;&lt;param name="EmbedMovie" value="0" /&gt;&lt;param name="SeamlessTabbing" value="1" /&gt;&lt;param name="Profile" value="0" /&gt;&lt;param name="ProfilePort" value="0" /&gt;&lt;param name="AllowNetworking" value="all" /&gt;&lt;param name="AllowFullScreen" value="false" /&gt;&lt;/object&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;a highlighterid="highlighter_431587" commandname="printSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#printSource" title="print"  style="width: 16px; height: 16px;"&gt;print&lt;/a&gt;&lt;a highlighterid="highlighter_431587" commandname="about" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#about" title="?"  style="width: 16px; height: 16px;"&gt;?&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;01&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;void&lt;/code&gt; &lt;code &gt;Handle_MouseLeftButtonUp(&lt;/code&gt;&lt;code &gt;object&lt;/code&gt; &lt;code &gt;sender, MouseButtonEventArgs e) &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;02&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;03&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;DragObject dragObj = sender &lt;/code&gt;&lt;code &gt;as&lt;/code&gt; &lt;code &gt;DragObject; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;04&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(sender &lt;/code&gt;&lt;code &gt;is&lt;/code&gt; &lt;code &gt;Canvas)&amp;nbsp; &lt;/code&gt;&lt;code &gt;// 鼠标左键在容器上弹起 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;05&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;06&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(isMouseCaptured) &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;07&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;08&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;isMouseCaptured = &lt;/code&gt;&lt;code &gt;false&lt;/code&gt;&lt;code &gt;; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;09&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(!rootCanvas.Children.Contains(curDrag)) &lt;/code&gt;&lt;code &gt;// 复制控件 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;11&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;double&lt;/code&gt; &lt;code &gt;x = e.GetPosition(rootCanvas).X; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;12&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;double&lt;/code&gt; &lt;code &gt;y = e.GetPosition(rootCanvas).Y; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;13&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;rootCanvas.Children.Add(&lt;/code&gt;&lt;code &gt;new&lt;/code&gt; &lt;code &gt;DragObject &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;15&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;16&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;ImageUri = curDrag.ImageUri, &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;17&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;UUID = curDrag.UUID, &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;18&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;ClickPos = curDrag.ClickPos &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;19&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;}); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;20&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;21&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;// 添加控件的鼠标左键按下、弹起事件、设置控件的位置 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;22&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;DragObject obj = rootCanvas.Children.First(ue =&amp;gt; (ue &lt;/code&gt;&lt;code &gt;as&lt;/code&gt; &lt;code &gt;DragObject).UUID == curDrag.UUID) &lt;/code&gt;&lt;code &gt;as&lt;/code&gt; &lt;code &gt;DragObject; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;23&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;//obj.MouseMove += Handle_MouseMove; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;24&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;obj.MouseLeftButtonDown += Handle_MouseLeftButtonDown; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;25&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;26&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;obj.SetValue(Canvas.TopProperty, y - obj.ClickPos.Y); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;27&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;obj.SetValue(Canvas.LeftProperty, x - obj.ClickPos.X); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;28&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;29&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;30&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;31&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;}&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;有了以上的代码就可以实现用户控件的复制了。接下实现 Canvas 容器中的控件的拖动事件，拖动控件的是在控件上按下鼠标左键，然后移动鼠标，因此控件需要处理鼠标左键按下和鼠标移动事件。处理代码如下： &lt;/p&gt;&#xD;
&lt;div  id="highlighter_461410"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&lt;a highlighterid="highlighter_461410" commandname="viewSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#viewSource" title="view plain"  style="width: 16px; height: 16px;"&gt;view plain&lt;/a&gt;&#xD;
&lt;div &gt;&#xD;
&lt;object height="16" width="16" type="application/x-shockwave-flash" id="highlighter_461410_clipboard"&gt;&#xD;
&lt;param name="Movie" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="Src" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="WMode" value="Transparent" /&gt;&lt;param name="Play" value="0" /&gt;&lt;param name="Loop" value="-1" /&gt;&lt;param name="Quality" value="High" /&gt;&lt;param name="Menu" value="0" /&gt;&lt;param name="AllowScriptAccess" value="always" /&gt;&lt;param name="Scale" value="ShowAll" /&gt;&lt;param name="DeviceFont" value="0" /&gt;&lt;param name="EmbedMovie" value="0" /&gt;&lt;param name="SeamlessTabbing" value="1" /&gt;&lt;param name="Profile" value="0" /&gt;&lt;param name="ProfilePort" value="0" /&gt;&lt;param name="AllowNetworking" value="all" /&gt;&lt;param name="AllowFullScreen" value="false" /&gt;&lt;/object&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;a highlighterid="highlighter_461410" commandname="printSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#printSource" title="print"  style="width: 16px; height: 16px;"&gt;print&lt;/a&gt;&lt;a highlighterid="highlighter_461410" commandname="about" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#about" title="?"  style="width: 16px; height: 16px;"&gt;?&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;01&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;void&lt;/code&gt; &lt;code &gt;Handle_MouseLeftButtonDown(&lt;/code&gt;&lt;code &gt;object&lt;/code&gt; &lt;code &gt;sender, MouseButtonEventArgs e) &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;02&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;03&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;DragObject dragObj = sender &lt;/code&gt;&lt;code &gt;as&lt;/code&gt; &lt;code &gt;DragObject; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;04&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(dragObj != &lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;)&amp;nbsp; &lt;/code&gt;&lt;code &gt;// 鼠标左键在 DragObject 上按下 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;05&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;06&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;dragObj.MouseMove -= Handle_MouseMove; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;07&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;dragObj.MouseMove += Handle_MouseMove; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;08&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;09&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;mouseVerticalPosition = e.GetPosition(&lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;).Y; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;mouseHorizontalPosition = e.GetPosition(&lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;).X; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;11&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;dragObj.CaptureMouse(); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;12&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;isMouseCaptured = &lt;/code&gt;&lt;code &gt;true&lt;/code&gt;&lt;code &gt;; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;13&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;}&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;鼠标移动事件处理代码如下： &lt;/p&gt;&#xD;
&lt;div  id="highlighter_396314"&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&lt;a highlighterid="highlighter_396314" commandname="viewSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#viewSource" title="view plain"  style="width: 16px; height: 16px;"&gt;view plain&lt;/a&gt;&#xD;
&lt;div &gt;&#xD;
&lt;object height="16" width="16" type="application/x-shockwave-flash" id="highlighter_396314_clipboard"&gt;&#xD;
&lt;param name="Movie" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="Src" value="http://blog.designbased.net/wp-content/plugins/syntax-highlighter/js/clipboard.swf" /&gt;&lt;param name="WMode" value="Transparent" /&gt;&lt;param name="Play" value="0" /&gt;&lt;param name="Loop" value="-1" /&gt;&lt;param name="Quality" value="High" /&gt;&lt;param name="Menu" value="0" /&gt;&lt;param name="AllowScriptAccess" value="always" /&gt;&lt;param name="Scale" value="ShowAll" /&gt;&lt;param name="DeviceFont" value="0" /&gt;&lt;param name="EmbedMovie" value="0" /&gt;&lt;param name="SeamlessTabbing" value="1" /&gt;&lt;param name="Profile" value="0" /&gt;&lt;param name="ProfilePort" value="0" /&gt;&lt;param name="AllowNetworking" value="all" /&gt;&lt;param name="AllowFullScreen" value="false" /&gt;&lt;/object&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;a highlighterid="highlighter_396314" commandname="printSource" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#printSource" title="print"  style="width: 16px; height: 16px;"&gt;print&lt;/a&gt;&lt;a highlighterid="highlighter_396314" commandname="about" href="http://blog.designbased.net/index.php/2010/08/silverlight-drag-and-copy-user-control/#about" title="?"  style="width: 16px; height: 16px;"&gt;?&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;01&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;void&lt;/code&gt; &lt;code &gt;Handle_MouseMove(&lt;/code&gt;&lt;code &gt;object&lt;/code&gt; &lt;code &gt;sender, MouseEventArgs e) &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;02&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;03&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;DragObject item = sender &lt;/code&gt;&lt;code &gt;as&lt;/code&gt; &lt;code &gt;DragObject; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;04&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;05&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;if&lt;/code&gt; &lt;code &gt;(item != &lt;/code&gt;&lt;code &gt;null&lt;/code&gt; &lt;code &gt;&amp;amp;&amp;amp; isMouseCaptured) &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;06&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;{ &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;07&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;double&lt;/code&gt; &lt;code &gt;deltaV = e.GetPosition(&lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;).Y - mouseVerticalPosition; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;08&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;double&lt;/code&gt; &lt;code &gt;deltaH = e.GetPosition(&lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;).X - mouseHorizontalPosition; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;09&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;double&lt;/code&gt; &lt;code &gt;newTop = deltaV + (&lt;/code&gt;&lt;code &gt;double&lt;/code&gt;&lt;code &gt;)item.GetValue(Canvas.TopProperty); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;double&lt;/code&gt; &lt;code &gt;newLeft = deltaH + (&lt;/code&gt;&lt;code &gt;double&lt;/code&gt;&lt;code &gt;)item.GetValue(Canvas.LeftProperty); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;11&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;12&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;// 设置新位置 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;13&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;item.SetValue(Canvas.TopProperty, newTop); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;item.SetValue(Canvas.LeftProperty, newLeft); &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;15&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&lt;/code&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;16&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;// 更新全局变量 &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;17&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;mouseVerticalPosition = e.GetPosition(&lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;).Y; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;18&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;mouseHorizontalPosition = e.GetPosition(&lt;/code&gt;&lt;code &gt;null&lt;/code&gt;&lt;code &gt;).X; &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;19&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;} &lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;table&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td &gt;&lt;code&gt;20&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;td &gt;&lt;code &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code &gt;}&lt;/code&gt;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;通过以上代码我们实现的拖动复制及移动控件，但是上面的代码还有一些小 Bug， 完整的示例代码请到&lt;a href="http://zdd.me/myfiles"&gt;http://zdd.me/myfiles&lt;/a&gt;下载。&lt;/p&gt;&#xD;
&lt;p style="text-align: left;"&gt;下面是演示：&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p style="text-align: left;"&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/forgetu/aggbug/1814135.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/forgetu/archive/2010/08/31/silverlight-drag-as-copy-usercontrol.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
