このチュートリアルでは、Windows Presentation Foundation (WPF) でのドラッグ アンド ドロップ データ転送に参加できるカスタム ユーザー コントロールを作成する方法について説明します。
このチュートリアルでは、円の図形を表すカスタム WPF UserControl を作成します。 ドラッグ アンド ドロップでデータ転送を有効にする機能をコントロールに実装します。 たとえば、ある円コントロールから別の円コントロールにドラッグすると、塗りつぶし色のデータがソースの円からターゲットの円にコピーされます。 円コントロールから TextBoxにドラッグすると、塗りつぶし色の文字列表現が TextBoxにコピーされます。 また、ドラッグ アンド ドロップ機能をテストするための 2 つのパネル コントロールと TextBox を含む小さなアプリケーションを作成します。 削除された円データをパネルが処理できるようにするコードを記述します。これにより、あるパネルの Children コレクションから他のパネルに円を移動またはコピーできます。
このチュートリアルでは、次のタスクについて説明します。
カスタム ユーザー コントロールを作成します。
ユーザー コントロールをドラッグ ソースとして有効にします。
ユーザー コントロールがドロップ ターゲットに設定されるようにします。
パネルがユーザー コントロールから削除されたデータを受信できるようにします。
[前提条件]
このチュートリアルを完了するには、Visual Studio が必要です。
アプリケーション プロジェクトを作成する
このセクションでは、2 つのパネルと TextBoxを含むメイン ページを含むアプリケーション インフラストラクチャを作成します。
DragDropExample
という名前の Visual Basic または Visual C# で新しい WPF アプリケーション プロジェクトを作成します。 詳細については、「チュートリアル: 初めての WPF デスクトップ アプリケーションの」を参照してください。MainWindow.xaml を開きます。
Gridタグの開始タグと終了タグの間に次のマークアップを追加します。
このマークアップにより、テスト アプリケーションのユーザー インターフェイスが作成されます。
<Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0" Background="Beige"> <TextBox Width="Auto" Margin="2" Text="green"/> </StackPanel> <StackPanel Grid.Column="1" Background="Bisque"> </StackPanel>
新しいユーザー コントロールをプロジェクトに追加する
このセクションでは、新しいユーザー コントロールをプロジェクトに追加します。
[プロジェクト] メニューの [ユーザー コントロール 追加]を選択します。
[
新しい項目の追加 ] ダイアログ ボックスで、名前を [] に変更し、[の追加] クリックします。 Circle.xaml とその分離コードがプロジェクトに追加されます。
Circle.xaml を開きます。
このファイルには、ユーザー コントロールのユーザー インターフェイス要素が含まれます。
ルート Grid に次のマークアップを追加して、UI として青い円を持つ単純なユーザー コントロールを作成します。
<Ellipse x:Name="circleUI" Height="100" Width="100" Fill="Blue" />
Circle.xaml.csまたはCircle.xaml.vbを開きます。
C# で、パラメーターなしのコンストラクターの後に次のコードを追加して、コピー コンストラクターを作成します。 Visual Basic で、パラメーターなしのコンストラクターとコピー コンストラクターの両方を作成する次のコードを追加します。
ユーザー コントロールをコピーできるようにするには、分離コード ファイルにコピー コンストラクター メソッドを追加します。 簡略化された Circle ユーザー コントロールでは、Fill とユーザー コントロールのサイズのみをコピーします。
public Circle(Circle c) { InitializeComponent(); this.circleUI.Height = c.circleUI.Height; this.circleUI.Width = c.circleUI.Height; this.circleUI.Fill = c.circleUI.Fill; }
Public Sub New() ' This call is required by the designer. InitializeComponent() End Sub Public Sub New(ByVal c As Circle) InitializeComponent() Me.circleUI.Height = c.circleUI.Height Me.circleUI.Width = c.circleUI.Height Me.circleUI.Fill = c.circleUI.Fill End Sub
メイン ウィンドウにユーザー コントロールを追加する
MainWindow.xaml を開きます。
次の XAML を Window タグの開始部分に追加して、現在のアプリケーションへの XML 名前空間参照を作成します。
xmlns:local="clr-namespace:DragDropExample"
最初の StackPanelで、次の XAML を追加して、最初のパネルに Circle ユーザー コントロールの 2 つのインスタンスを作成します。
<local:Circle Margin="2" /> <local:Circle Margin="2" />
パネルの完全な XAML は次のようになります。
<StackPanel Grid.Column="0" Background="Beige"> <TextBox Width="Auto" Margin="2" Text="green"/> <local:Circle Margin="2" /> <local:Circle Margin="2" /> </StackPanel> <StackPanel Grid.Column="1" Background="Bisque"> </StackPanel>
ユーザー コントロールにドラッグ ソース イベントを実装する
このセクションでは、OnMouseMove メソッドをオーバーライドし、ドラッグ アンド ドロップ操作を開始します。
ドラッグが開始された場合 (マウス ボタンが押され、マウスが移動された場合)、DataObjectに転送するデータをパッケージ化します。 この場合、円コントロールは、3 つのデータ項目 (塗りつぶし色の文字列表現、高さの double 表現、それ自体のコピー) をパッケージ化します。
ドラッグ アンド ドロップ操作を開始するには
Circle.xaml.csまたはCircle.xaml.vbを開きます。
次の OnMouseMove オーバーライドを追加して、MouseMove イベントのクラス処理を提供します。
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.LeftButton == MouseButtonState.Pressed) { // Package the data. DataObject data = new DataObject(); data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString()); data.SetData("Double", circleUI.Height); data.SetData("Object", this); // Initiate the drag-and-drop operation. DragDrop.DoDragDrop(this, data, DragDropEffects.Copy | DragDropEffects.Move); } }
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Input.MouseEventArgs) MyBase.OnMouseMove(e) If e.LeftButton = MouseButtonState.Pressed Then ' Package the data. Dim data As New DataObject data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString()) data.SetData("Double", circleUI.Height) data.SetData("Object", Me) ' Inititate the drag-and-drop operation. DragDrop.DoDragDrop(Me, data, DragDropEffects.Copy Or DragDropEffects.Move) End If End Sub
この OnMouseMove オーバーライドでは、次のタスクが実行されます。
マウスの移動中にマウスの左ボタンが押されているかどうかを確認します。
Circle データを DataObjectにパッケージ化します。 この場合、円コントロールは、3 つのデータ項目 (塗りつぶし色の文字列表現、高さの double 表現、それ自体のコピー) をパッケージ化します。
静的 DragDrop.DoDragDrop メソッドを呼び出して、ドラッグ アンド ドロップ操作を開始します。 DoDragDrop メソッドには、次の 3 つのパラメーターを渡します。
dragSource
– このコントロールへの参照。data
– 前のコードで作成した DataObject。
F5
押して、アプリケーションをビルドして実行します。 いずれかの円コントロールをクリックしてパネル、もう一方の円、TextBox にドラッグします。 TextBox上をドラッグすると、カーソルが移動を示すように変わります。
TextBoxの上に円をドラッグしながら、Ctrl キーを押 キーを押します。 カーソルがどのように変化してコピーを示しているかに注目してください。
円を TextBoxにドラッグ アンド ドロップします。 円の塗りつぶし色の文字列表現が TextBox に追加されます。
既定では、ドラッグ アンド ドロップ操作中にカーソルが変更され、データをドロップする効果が示されます。 GiveFeedback イベントを処理し、別のカーソルを設定することで、ユーザーに与えられたフィードバックをカスタマイズできます。
ユーザーにフィードバックを送信する
Circle.xaml.csまたはCircle.xaml.vbを開きます。
次の OnGiveFeedback オーバーライドを追加して、GiveFeedback イベントのクラス処理を提供します。
protected override void OnGiveFeedback(GiveFeedbackEventArgs e) { base.OnGiveFeedback(e); // These Effects values are set in the drop target's // DragOver event handler. if (e.Effects.HasFlag(DragDropEffects.Copy)) { Mouse.SetCursor(Cursors.Cross); } else if (e.Effects.HasFlag(DragDropEffects.Move)) { Mouse.SetCursor(Cursors.Pen); } else { Mouse.SetCursor(Cursors.No); } e.Handled = true; }
Protected Overrides Sub OnGiveFeedback(ByVal e As System.Windows.GiveFeedbackEventArgs) MyBase.OnGiveFeedback(e) ' These Effects values are set in the drop target's ' DragOver event handler. If e.Effects.HasFlag(DragDropEffects.Copy) Then Mouse.SetCursor(Cursors.Cross) ElseIf e.Effects.HasFlag(DragDropEffects.Move) Then Mouse.SetCursor(Cursors.Pen) Else Mouse.SetCursor(Cursors.No) End If e.Handled = True End Sub
この OnGiveFeedback オーバーライドでは、次のタスクが実行されます。
F5
押して、アプリケーションをビルドして実行します。 いずれかの円コントロールをパネル、もう一方の円、TextBox にドラッグします。 カーソルが、OnGiveFeedback オーバーライドで指定したカスタム カーソルであることに注意してください。
green
からテキスト TextBox を選択します。green
テキストを Circle コントロールにドラッグします。 ドラッグ アンド ドロップ操作の効果を示す既定のカーソルが表示されていることに注意してください。 フィードバック カーソルは、常にドラッグ ソースによって設定されます。
ユーザー コントロールにドロップ ターゲット イベントを実装する
このセクションでは、ユーザー コントロールがドロップ ターゲットであることを指定し、ユーザー コントロールをドロップ ターゲットにするメソッドをオーバーライドし、ドロップ先のデータを処理します。
ユーザー コントロールをドロップ ターゲットとして有効にする手順
Circle.xaml を開きます。
開始 UserControl タグで、AllowDrop プロパティを追加し、
true
に設定します。<UserControl x:Class="DragDropWalkthrough.Circle" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" AllowDrop="True">
OnDrop メソッドは、AllowDrop プロパティが true
に設定され、ドラッグ ソースからのデータが Circle ユーザー コントロールにドロップされるときに呼び出されます。 このメソッドでは、削除されたデータを処理し、そのデータを Circle に適用します。
ドロップされたデータを処理する手順
Circle.xaml.csまたはCircle.xaml.vbを開きます。
次の OnDrop オーバーライドを追加して、Drop イベントのクラス処理を提供します。
protected override void OnDrop(DragEventArgs e) { base.OnDrop(e); // If the DataObject contains string data, extract it. if (e.Data.GetDataPresent(DataFormats.StringFormat)) { string dataString = (string)e.Data.GetData(DataFormats.StringFormat); // If the string can be converted into a Brush, // convert it and apply it to the ellipse. BrushConverter converter = new BrushConverter(); if (converter.IsValid(dataString)) { Brush newFill = (Brush)converter.ConvertFromString(dataString); circleUI.Fill = newFill; // Set Effects to notify the drag source what effect // the drag-and-drop operation had. // (Copy if CTRL is pressed; otherwise, move.) if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey)) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.Move; } } } e.Handled = true; }
Protected Overrides Sub OnDrop(ByVal e As System.Windows.DragEventArgs) MyBase.OnDrop(e) ' If the DataObject contains string data, extract it. If e.Data.GetDataPresent(DataFormats.StringFormat) Then Dim dataString As String = e.Data.GetData(DataFormats.StringFormat) ' If the string can be converted into a Brush, ' convert it and apply it to the ellipse. Dim converter As New BrushConverter If converter.IsValid(dataString) Then Dim newFill As Brush = converter.ConvertFromString(dataString) circleUI.Fill = newFill ' Set Effects to notify the drag source what effect ' the drag-and-drop operation had. ' (Copy if CTRL is pressed; otherwise, move.) If e.KeyStates.HasFlag(DragDropKeyStates.ControlKey) Then e.Effects = DragDropEffects.Copy Else e.Effects = DragDropEffects.Move End If End If End If e.Handled = True End Sub
この OnDrop オーバーライドでは、次のタスクが実行されます。
GetDataPresent メソッドを使用して、ドラッグされたデータに文字列オブジェクトが含まれているかどうかを確認します。
文字列データが存在する場合は、GetData メソッドを使用して抽出します。
BrushConverter を使用して文字列を Brushに変換します。
Drop イベントを処理済みとしてマークします。 このイベントを受け取る他の要素が Circle ユーザー コントロールによって処理されたことを認識できるように、ドロップ イベントを処理済みとしてマークする必要があります。
F5
押して、アプリケーションをビルドして実行します。 green
内のテキスト TextBox を選択します。テキストを Circle コントロールにドラッグしてドロップします。 円は青から緑に変わります。
に変換する
green
にテキスト TextBox を入力します。gre
内のテキスト TextBox を選択します。それをCircle コントロールにドラッグしてドロップします。 ドロップが許可されていることを示すためにカーソルが変わりますが、
gre
が有効な色ではないため、円の色は変更されないことに注意してください。緑の円コントロールからドラッグし、青い円コントロールにドロップします。 円は青から緑に変わります。 表示されるカーソルは、TextBox と円のどちらがドラッグ ソースであるかによって異なります。
AllowDrop プロパティを true
に設定し、ドロップされたデータを処理するだけで、要素をドロップ ターゲットにすることができます。 ただし、より優れたユーザー エクスペリエンスを提供するには、DragEnter、DragLeave、および DragOver イベントも処理する必要があります。 これらのイベントでは、データが削除される前に、チェックを実行し、ユーザーに追加のフィードバックを提供できます。
Circle ユーザー コントロールの上にデータをドラッグすると、ドラッグ元に、ドラッグされているデータを処理できるかどうかを通知する必要があります。 コントロールがデータの処理方法を知らない場合は、ドロップを拒否する必要があります。 これを行うには、DragOver イベントを処理し、Effects プロパティを設定します。
データドロップが許可されていることを確認するには
Circle.xaml.csまたはCircle.xaml.vbを開きます。
次の OnDragOver オーバーライドを追加して、DragOver イベントのクラス処理を提供します。
protected override void OnDragOver(DragEventArgs e) { base.OnDragOver(e); e.Effects = DragDropEffects.None; // If the DataObject contains string data, extract it. if (e.Data.GetDataPresent(DataFormats.StringFormat)) { string dataString = (string)e.Data.GetData(DataFormats.StringFormat); // If the string can be converted into a Brush, allow copying or moving. BrushConverter converter = new BrushConverter(); if (converter.IsValid(dataString)) { // Set Effects to notify the drag source what effect // the drag-and-drop operation will have. These values are // used by the drag source's GiveFeedback event handler. // (Copy if CTRL is pressed; otherwise, move.) if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey)) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.Move; } } } e.Handled = true; }
Protected Overrides Sub OnDragOver(ByVal e As System.Windows.DragEventArgs) MyBase.OnDragOver(e) e.Effects = DragDropEffects.None ' If the DataObject contains string data, extract it. If e.Data.GetDataPresent(DataFormats.StringFormat) Then Dim dataString As String = e.Data.GetData(DataFormats.StringFormat) ' If the string can be converted into a Brush, allow copying or moving. Dim converter As New BrushConverter If converter.IsValid(dataString) Then ' Set Effects to notify the drag source what effect ' the drag-and-drop operation will have. These values are ' used by the drag source's GiveFeedback event handler. ' (Copy if CTRL is pressed; otherwise, move.) If e.KeyStates.HasFlag(DragDropKeyStates.ControlKey) Then e.Effects = DragDropEffects.Copy Else e.Effects = DragDropEffects.Move End If End If End If e.Handled = True End Sub
この OnDragOver オーバーライドでは、次のタスクが実行されます。
F5
押して、アプリケーションをビルドして実行します。 gre
内のテキスト TextBox を選択します。テキストを Circle コントロールにドラッグします。 カーソルが変更され、
gre
が有効な色ではないため、ドロップが許可されていないことを示します。
ドロップ操作のプレビューを適用することで、ユーザー エクスペリエンスをさらに強化できます。 Circle ユーザー コントロールでは、OnDragEnter メソッドと OnDragLeave メソッドをオーバーライドします。 データをコントロールの上にドラッグすると、現在の背景 Fill がプレースホルダー変数に保存されます。 文字列はブラシに変換され、Circle の UI を提供する Ellipse に適用されます。 データがドロップされずに円からドラッグされた場合、元の Fill 値が円に再適用されます。
ドラッグ アンド ドロップ操作の効果をプレビューするには
Circle.xaml.csまたはCircle.xaml.vbを開きます。
Circle クラスで、Brush という名前のプライベート
_previousFill
変数を宣言し、それをnull
に初期化します。public partial class Circle : UserControl { private Brush _previousFill = null;
Public Class Circle Private _previousFill As Brush = Nothing
次の OnDragEnter オーバーライドを追加して、DragEnter イベントのクラス処理を提供します。
protected override void OnDragEnter(DragEventArgs e) { base.OnDragEnter(e); // Save the current Fill brush so that you can revert back to this value in DragLeave. _previousFill = circleUI.Fill; // If the DataObject contains string data, extract it. if (e.Data.GetDataPresent(DataFormats.StringFormat)) { string dataString = (string)e.Data.GetData(DataFormats.StringFormat); // If the string can be converted into a Brush, convert it. BrushConverter converter = new BrushConverter(); if (converter.IsValid(dataString)) { Brush newFill = (Brush)converter.ConvertFromString(dataString.ToString()); circleUI.Fill = newFill; } } }
Protected Overrides Sub OnDragEnter(ByVal e As System.Windows.DragEventArgs) MyBase.OnDragEnter(e) _previousFill = circleUI.Fill ' If the DataObject contains string data, extract it. If e.Data.GetDataPresent(DataFormats.StringFormat) Then Dim dataString As String = e.Data.GetData(DataFormats.StringFormat) ' If the string can be converted into a Brush, convert it. Dim converter As New BrushConverter If converter.IsValid(dataString) Then Dim newFill As Brush = converter.ConvertFromString(dataString) circleUI.Fill = newFill End If End If e.Handled = True End Sub
この OnDragEnter オーバーライドでは、次のタスクが実行されます。
次の OnDragLeave オーバーライドを追加して、DragLeave イベントのクラス処理を提供します。
protected override void OnDragLeave(DragEventArgs e) { base.OnDragLeave(e); // Undo the preview that was applied in OnDragEnter. circleUI.Fill = _previousFill; }
Protected Overrides Sub OnDragLeave(ByVal e As System.Windows.DragEventArgs) MyBase.OnDragLeave(e) ' Undo the preview that was applied in OnDragEnter. circleUI.Fill = _previousFill End Sub
この OnDragLeave オーバーライドでは、次のタスクが実行されます。
F5
押して、アプリケーションをビルドして実行します。 green
内のテキスト TextBox を選択します。テキストをドラッグして円コントロールの上に移動しますが、ドロップしないでください。 円は青から緑に変わります。
円コントロールからテキストをドラッグします。 円は緑色から青に変わります。
パネルがドロップされたデータを受信できるようにする
このセクションでは、Circle ユーザー コントロールをホストするパネルを、ドラッグされた Circle データのドロップ ターゲットとして機能させます。 円をパネル間で移動したり、Ctrl キーを押しながら円をドラッグ アンド ドロップして円コントロールのコピーを作成したりできるようにするコードを実装します。
MainWindow.xaml を開きます。
次の XAML に示すように、各 StackPanel コントロールで、DragOver イベントと Drop イベントのハンドラーを追加します。 DragOver イベント ハンドラーに名前を付け、
panel_DragOver
とし、Drop イベント ハンドラーに名前を付け、panel_Drop
とする。デフォルトでは、パネルはドロップの対象になりません。 有効にするには、両方のパネルに AllowDrop プロパティを追加し、値を
true
に設定します。<StackPanel Grid.Column="0" Background="Beige" AllowDrop="True" DragOver="panel_DragOver" Drop="panel_Drop"> <TextBox Width="Auto" Margin="2" Text="green"/> <local:Circle Margin="2" /> <local:Circle Margin="2" /> </StackPanel> <StackPanel Grid.Column="1" Background="Bisque" AllowDrop="True" DragOver="panel_DragOver" Drop="panel_Drop"> </StackPanel>
MainWindows.xaml.csまたはMainWindow.xaml.vbを開きます。
DragOver イベント ハンドラーの次のコードを追加します。
private void panel_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent("Object")) { // These Effects values are used in the drag source's // GiveFeedback event handler to determine which cursor to display. if (e.KeyStates == DragDropKeyStates.ControlKey) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.Move; } } }
Private Sub panel_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs) If e.Data.GetDataPresent("Object") Then ' These Effects values are used in the drag source's ' GiveFeedback event handler to determine which cursor to display. If e.KeyStates = DragDropKeyStates.ControlKey Then e.Effects = DragDropEffects.Copy Else e.Effects = DragDropEffects.Move End If End If End Sub
この DragOver イベント ハンドラーは、次のタスクを実行します。
ドラッグされたデータに、Circle ユーザー コントロールによって DataObject にパッケージ化され、DoDragDropへの呼び出しで渡された "Object" データが含まれていることを確認します。
"Object" データが存在する場合は、Ctrl キーが押されているかどうかを確認します。
Ctrl キーを押した場合は、Effects プロパティを Copyに設定します。 それ以外の場合は、Effects プロパティを Moveに設定します。
Drop イベント ハンドラーの次のコードを追加します。
private void panel_Drop(object sender, DragEventArgs e) { // If an element in the panel has already handled the drop, // the panel should not also handle it. if (e.Handled == false) { Panel _panel = (Panel)sender; UIElement _element = (UIElement)e.Data.GetData("Object"); if (_panel != null && _element != null) { // Get the panel that the element currently belongs to, // then remove it from that panel and add it the Children of // the panel that its been dropped on. Panel _parent = (Panel)VisualTreeHelper.GetParent(_element); if (_parent != null) { if (e.KeyStates == DragDropKeyStates.ControlKey && e.AllowedEffects.HasFlag(DragDropEffects.Copy)) { Circle _circle = new Circle((Circle)_element); _panel.Children.Add(_circle); // set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Copy; } else if (e.AllowedEffects.HasFlag(DragDropEffects.Move)) { _parent.Children.Remove(_element); _panel.Children.Add(_element); // set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Move; } } } } }
Private Sub panel_Drop(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs) ' If an element in the panel has already handled the drop, ' the panel should not also handle it. If e.Handled = False Then Dim _panel As Panel = sender Dim _element As UIElement = e.Data.GetData("Object") If _panel IsNot Nothing And _element IsNot Nothing Then ' Get the panel that the element currently belongs to, ' then remove it from that panel and add it the Children of ' the panel that its been dropped on. Dim _parent As Panel = VisualTreeHelper.GetParent(_element) If _parent IsNot Nothing Then If e.KeyStates = DragDropKeyStates.ControlKey And _ e.AllowedEffects.HasFlag(DragDropEffects.Copy) Then Dim _circle As New Circle(_element) _panel.Children.Add(_circle) ' set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Copy ElseIf e.AllowedEffects.HasFlag(DragDropEffects.Move) Then _parent.Children.Remove(_element) _panel.Children.Add(_element) ' set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Move End If End If End If End If End Sub
この Drop イベント ハンドラーは、次のタスクを実行します。
Drop イベントが既に処理されているかどうかを確認します。 たとえば、Drop イベントを処理する別の Circle に円がドロップされた場合、その円を含むパネルも処理しないようにします。
Drop イベントが処理されない場合は、Ctrl キーが押されているかどうかを確認します。
が発生したときに Drop キーが押された場合は、Circle コントロールのコピーを作成し、Childrenの StackPanel コレクションに追加します。
Ctrl キーが押されていない場合は、親パネルの Children コレクションから、削除されたパネルの Children コレクションに Circle を移動します。
移動操作またはコピー操作が実行されたかどうかを Effects メソッドに通知する DoDragDrop プロパティを設定します。
F5
押して、アプリケーションをビルドして実行します。 green
からテキスト TextBox を選択します。円コントロールの上にテキストをドラッグし、ドロップします。
円コントロールを左パネルから右パネルにドラッグし、ドロップします。 円は、左側のパネルの Children コレクションから削除され、右側のパネルの Children コレクションに追加されます。
元のパネルから円コントロールを他のパネルにCtrlキーを押しながらドラッグしてドロップします。 円が複製され、その複製が受信パネルの Children コレクションに追加されます。
こちらも参照ください
.NET Desktop feedback