Control.DoDragDrop メソッド

定義

オーバーロード

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean)

ドラッグ操作を開始します。

DoDragDrop(Object, DragDropEffects)

ドラッグ アンド ドロップ操作を開始します。

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean)

ドラッグ操作を開始します。

C#
public System.Windows.Forms.DragDropEffects DoDragDrop (object data, System.Windows.Forms.DragDropEffects allowedEffects, System.Drawing.Bitmap? dragImage, System.Drawing.Point cursorOffset, bool useDefaultDragImage);

パラメーター

data
Object
allowedEffects
DragDropEffects
dragImage
Bitmap
cursorOffset
Point
useDefaultDragImage
Boolean

戻り値

ドラッグ アンド ドロップ操作中に実行された最終的な効果を表す DragDropEffects 列挙体の値。

注釈

allowedEffects パラメーターは、実行できるドラッグ操作を決定します。 ドラッグ操作を別のプロセスのアプリケーションと相互運用する必要がある場合、data は基底マネージド クラス (StringBitmap、または Metafile) か、ISerializableを実装する Object のいずれかである必要があります。 data は、IDataObjectを実装する任意の Object にすることもできます。 dragImage はドラッグ操作中に表示されるビットマップであり、cursorOffset は左上隅からのオフセットである dragImage内のカーソルの位置を指定します。 useDefaultDragImage のサイズが 96 x 96 のレイヤード ウィンドウドラッグイメージを使用する true を指定します。それ以外の場合は false。 イメージの幅または高さが 300 ピクセルを超えると、dragImage の外側のエッジがブレンドされることに注意してください。

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean) は常にアルファ値を計算する際に RGB 乗算ステップを実行するため、事前乗算されたアルファ ブレンドを使用せずに常に Bitmap を渡す必要があります。 事前乗算されたアルファ ブレンドで Bitmap を渡してもエラーは発生しませんが、このメソッドは再度乗算し、結果のアルファ値を 2 倍にします。

適用対象

Windows Desktop 9 およびその他のバージョン
製品 バージョン
Windows Desktop 7, 8, 9

DoDragDrop(Object, DragDropEffects)

ドラッグ アンド ドロップ操作を開始します。

C#
public System.Windows.Forms.DragDropEffects DoDragDrop (object data, System.Windows.Forms.DragDropEffects allowedEffects);

パラメーター

data
Object

ドラッグするデータ。

allowedEffects
DragDropEffects

DragDropEffects 値の 1 つ。

戻り値

ドラッグ アンド ドロップ操作中に実行された最終的な効果を表す DragDropEffects 列挙体の値。

次のコード例は、2 つの ListBox コントロール間のドラッグ アンド ドロップ操作を示しています。 この例では、ドラッグ アクションの開始時に DoDragDrop メソッドを呼び出します。 ドラッグ 操作は、MouseDown イベント中にマウスの位置からマウスが SystemInformation.DragSize 以上移動した場合に開始されます。 IndexFromPoint メソッドは、MouseDown イベント中にドラッグする項目のインデックスを決定するために使用されます。

この例では、ドラッグ アンド ドロップ操作にカスタム カーソルを使用する方法も示します。 この例では、カスタム ドラッグ カーソルとドロップなしのカーソルに対して、それぞれ 2 つのカーソル ファイル (3dwarro.cur3dwno.cur) がアプリケーション ディレクトリに存在している必要があります。 UseCustomCursorsCheck CheckBox がチェックされている場合は、カスタム カーソルが使用されます。 カスタム カーソルは、GiveFeedback イベント ハンドラーで設定されます。

キーボードの状態は、右 ListBoxDragOver イベント ハンドラーで評価され、Shift キー、Ctrl キー、Alt キー、または Ctrl + Alt キーの状態に基づいてドラッグ操作を決定します。 ドロップが発生する ListBox 内の場所も、DragOver イベント中に決定されます。 削除するデータが Stringでない場合、DragEventArgs.EffectDragDropEffectsNone に設定されます。 最後に、ドロップの状態が DropLocationLabelLabelに表示されます。

適切な ListBox に対して削除するデータは、DragDrop イベント ハンドラーで決定され、String 値は ListBoxの適切な場所に追加されます。 ドラッグ操作がフォームの境界外に移動すると、QueryContinueDrag イベント ハンドラーでドラッグ アンド ドロップ操作が取り消されます。

C#
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Snip_DragNDrop
{
    public class Form1 : Form
    {
        private ListBox ListDragSource;
        private ListBox ListDragTarget;
        private CheckBox UseCustomCursorsCheck;
        private Label DropLocationLabel;

        private int indexOfItemUnderMouseToDrag;
        private int indexOfItemUnderMouseToDrop;

        private Rectangle dragBoxFromMouseDown;
        private Point screenOffset;

        private Cursor MyNoDropCursor;
        private Cursor MyNormalCursor;

        // The main entry point for the application.
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        public Form1()
        {
            this.ListDragSource = new ListBox();
            this.ListDragTarget = new ListBox();
            this.UseCustomCursorsCheck = new CheckBox();
            this.DropLocationLabel = new Label();

            this.SuspendLayout();

            // ListDragSource
            this.ListDragSource.Items.AddRange(new object[] {"one", "two", "three", "four",
                                                             "five", "six", "seven", "eight",
                                                             "nine", "ten"});
            this.ListDragSource.Location = new Point(10, 17);
            this.ListDragSource.Size = new Size(120, 225);
            this.ListDragSource.MouseDown += this.ListDragSource_MouseDown;
            this.ListDragSource.QueryContinueDrag += this.ListDragSource_QueryContinueDrag;
            this.ListDragSource.MouseUp += this.ListDragSource_MouseUp;
            this.ListDragSource.MouseMove += this.ListDragSource_MouseMove;
            this.ListDragSource.GiveFeedback += this.ListDragSource_GiveFeedback;

            // ListDragTarget
            this.ListDragTarget.AllowDrop = true;
            this.ListDragTarget.Location = new Point(154, 17);
            this.ListDragTarget.Size = new Size(120, 225);
            this.ListDragTarget.DragOver += this.ListDragTarget_DragOver;
            this.ListDragTarget.DragDrop += this.ListDragTarget_DragDrop;
            this.ListDragTarget.DragEnter += this.ListDragTarget_DragEnter;
            this.ListDragTarget.DragLeave += this.ListDragTarget_DragLeave;

            // UseCustomCursorsCheck
            this.UseCustomCursorsCheck.Location = new Point(10, 243);
            this.UseCustomCursorsCheck.Size = new Size(137, 24);
            this.UseCustomCursorsCheck.Text = "Use Custom Cursors";

            // DropLocationLabel
            this.DropLocationLabel.Location = new Point(154, 245);
            this.DropLocationLabel.Size = new Size(137, 24);
            this.DropLocationLabel.Text = "None";

            // Form1
            this.ClientSize = new Size(292, 270);
            this.Controls.AddRange(new Control[] {
                this.ListDragSource,
                this.ListDragTarget,
                this.UseCustomCursorsCheck,
                this.DropLocationLabel});
            this.Text = "drag-and-drop Example";

            this.ResumeLayout(false);
        }

        private void ListDragSource_MouseDown(object sender, MouseEventArgs e)
        {
            // Get the index of the item the mouse is below.
            indexOfItemUnderMouseToDrag = ListDragSource.IndexFromPoint(e.X, e.Y);

            if (indexOfItemUnderMouseToDrag != ListBox.NoMatches)
            {
                // Remember the point where the mouse down occurred. The DragSize indicates
                // the size that the mouse can move before a drag event should be started.
                Size dragSize = SystemInformation.DragSize;

                // Create a rectangle using the DragSize, with the mouse position being
                // at the center of the rectangle.
                dragBoxFromMouseDown = new Rectangle(
                    new Point(e.X - (dragSize.Width / 2),
                              e.Y - (dragSize.Height / 2)),
                    dragSize);
            }
            else
            {
                // Reset the rectangle if the mouse is not over an item in the ListBox.
                dragBoxFromMouseDown = Rectangle.Empty;
            }
        }

        private void ListDragSource_MouseUp(object sender, MouseEventArgs e)
        {
            // Reset the drag rectangle when the mouse button is raised.
            dragBoxFromMouseDown = Rectangle.Empty;
        }

        private void ListDragSource_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                // If the mouse moves outside the rectangle, start the drag.
                if (dragBoxFromMouseDown != Rectangle.Empty &&
                    !dragBoxFromMouseDown.Contains(e.X, e.Y))
                {
                    // Create custom cursors for the drag-and-drop operation.
                    try
                    {
                        MyNormalCursor = new Cursor("3dwarro.cur");
                        MyNoDropCursor = new Cursor("3dwno.cur");
                    }
                    catch
                    {
                        // An error occurred while attempting to load the cursors, so use
                        // standard cursors.
                        UseCustomCursorsCheck.Checked = false;
                    }
                    finally
                    {
                        // The screenOffset is used to account for any desktop bands 
                        // that may be at the top or left side of the screen when 
                        // determining when to cancel the drag drop operation.
                        screenOffset = SystemInformation.WorkingArea.Location;

                        // Proceed with the drag-and-drop, passing in the list item.
                        DragDropEffects dropEffect = ListDragSource.DoDragDrop(ListDragSource.Items[indexOfItemUnderMouseToDrag], DragDropEffects.All | DragDropEffects.Link);

                        // If the drag operation was a move then remove the item.
                        if (dropEffect == DragDropEffects.Move)
                        {
                            ListDragSource.Items.RemoveAt(indexOfItemUnderMouseToDrag);

                            // Selects the previous item in the list as long as the list has an item.
                            if (indexOfItemUnderMouseToDrag > 0)
                                ListDragSource.SelectedIndex = indexOfItemUnderMouseToDrag - 1;

                            else if (ListDragSource.Items.Count > 0)
                                // Selects the first item.
                                ListDragSource.SelectedIndex = 0;
                        }

                        // Dispose of the cursors since they are no longer needed.
                        if (MyNormalCursor != null)
                            MyNormalCursor.Dispose();

                        if (MyNoDropCursor != null)
                            MyNoDropCursor.Dispose();
                    }
                }
            }
        }
        private void ListDragSource_GiveFeedback(object sender, GiveFeedbackEventArgs e)
        {
            // Use custom cursors if the check box is checked.
            if (UseCustomCursorsCheck.Checked)
            {
                // Sets the custom cursor based upon the effect.
                e.UseDefaultCursors = false;
                if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move)
                    Cursor.Current = MyNormalCursor;
                else
                    Cursor.Current = MyNoDropCursor;
            }
        }
        private void ListDragTarget_DragOver(object sender, DragEventArgs e)
        {
            // Determine whether string data exists in the drop data. If not, then
            // the drop effect reflects that the drop cannot occur.
            if (!e.Data.GetDataPresent(typeof(System.String)))
            {
                e.Effect = DragDropEffects.None;
                DropLocationLabel.Text = "None - no string data.";
                return;
            }

            // Set the effect based upon the KeyState.
            if ((e.KeyState & (8 + 32)) == (8 + 32) &&
                (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link)
            {
                // KeyState 8 + 32 = CTRL + ALT

                // Link drag-and-drop effect.
                e.Effect = DragDropEffects.Link;
            }
            else if ((e.KeyState & 32) == 32 &&
                (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link)
            {
                // ALT KeyState for link.
                e.Effect = DragDropEffects.Link;
            }
            else if ((e.KeyState & 4) == 4 &&
                (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
            {
                // SHIFT KeyState for move.
                e.Effect = DragDropEffects.Move;
            }
            else if ((e.KeyState & 8) == 8 &&
                (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
            {
                // CTRL KeyState for copy.
                e.Effect = DragDropEffects.Copy;
            }
            else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
            {
                // By default, the drop action should be move, if allowed.
                e.Effect = DragDropEffects.Move;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }

            // Get the index of the item the mouse is below. 

            // The mouse locations are relative to the screen, so they must be 
            // converted to client coordinates.

            indexOfItemUnderMouseToDrop =
                ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(new Point(e.X, e.Y)));

            // Updates the label text.
            if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
            {
                DropLocationLabel.Text = "Drops before item #" + (indexOfItemUnderMouseToDrop + 1);
            }
            else
            {
                DropLocationLabel.Text = "Drops at the end.";
            }
        }
        private void ListDragTarget_DragDrop(object sender, DragEventArgs e)
        {
            // Ensure that the list item index is contained in the data.
            if (e.Data.GetDataPresent(typeof(System.String)))
            {
                Object item = e.Data.GetData(typeof(System.String));

                // Perform drag-and-drop, depending upon the effect.
                if (e.Effect == DragDropEffects.Copy ||
                    e.Effect == DragDropEffects.Move)
                {
                    // Insert the item.
                    if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
                        ListDragTarget.Items.Insert(indexOfItemUnderMouseToDrop, item);
                    else
                        ListDragTarget.Items.Add(item);
                }
            }
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragSource_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            // Cancel the drag if the mouse moves off the form.
            ListBox lb = sender as ListBox;

            if (lb != null)
            {
                Form f = lb.FindForm();

                // Cancel the drag if the mouse moves off the form. The screenOffset
                // takes into account any desktop bands that may be at the top or left
                // side of the screen.
                if (((Control.MousePosition.X - screenOffset.X) < f.DesktopBounds.Left) ||
                    ((Control.MousePosition.X - screenOffset.X) > f.DesktopBounds.Right) ||
                    ((Control.MousePosition.Y - screenOffset.Y) < f.DesktopBounds.Top) ||
                    ((Control.MousePosition.Y - screenOffset.Y) > f.DesktopBounds.Bottom))
                {
                    e.Action = DragAction.Cancel;
                }
            }
        }
        private void ListDragTarget_DragEnter(object sender, DragEventArgs e)
        {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragTarget_DragLeave(object sender, EventArgs e)
        {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
    }
}

次のコード例は、DragDropEffects 列挙体を使用して、ドラッグ アンド ドロップ操作に関係するコントロール間でデータを転送する方法を指定する方法を示しています。 この例では、フォームに RichTextBox コントロールと ListBox コントロールが含まれており、ListBox コントロールに有効なファイル名の一覧が設定されている必要があります。 ユーザーがファイル名を RichTextBox コントロールにドラッグすると、コントロールの DragEnter イベントが発生します。 イベント ハンドラー内では、DragEventArgsEffect プロパティが DragDropEffects に初期化され、ファイル パスによって参照されるデータを RichTextBox コントロールにコピーする必要があることを示します。

C#
private void Form1_Load(object sender, EventArgs e) 
{
   // Sets the AllowDrop property so that data can be dragged onto the control.
   richTextBox1.AllowDrop = true;

   // Add code here to populate the ListBox1 with paths to text files.
}

private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
   // Determines which item was selected.
   ListBox lb =( (ListBox)sender);
   Point pt = new Point(e.X,e.Y);
   int index = lb.IndexFromPoint(pt);

   // Starts a drag-and-drop operation with that item.
   if(index>=0) 
   {
      lb.DoDragDrop(lb.Items[index].ToString(), DragDropEffects.Link);
   }
}

private void richTextBox1_DragEnter(object sender, DragEventArgs e) 
{
   // If the data is text, copy the data to the RichTextBox control.
   if(e.Data.GetDataPresent("Text"))
      e.Effect = DragDropEffects.Copy;
}

private void richTextBox1_DragDrop(object sender, DragEventArgs e) 
{
   // Loads the file into the control. 
   richTextBox1.LoadFile((String)e.Data.GetData("Text"), System.Windows.Forms.RichTextBoxStreamType.RichText);
}

注釈

allowedEffects パラメーターは、実行できるドラッグ操作を決定します。 ドラッグ操作を別のプロセスでアプリケーションと相互運用する必要がある場合、データは基底マネージド クラス (StringBitmap、または Metafile)、または ISerializable または IDataObjectを実装するオブジェクトである必要があります。

ドラッグ アンド ドロップ操作に関連するイベントが発生する方法とタイミングを次に示します。

DoDragDrop メソッドは、現在のカーソル位置のコントロールを決定します。 次に、コントロールが有効なドロップ ターゲットであるかどうかを確認します。

コントロールが有効なドロップ ターゲットの場合、ドラッグ アンド ドロップ効果が指定された状態で GiveFeedback イベントが発生します。 ドラッグ アンド ドロップ効果の一覧については、DragDropEffects 列挙型を参照してください。

マウス カーソルの位置、キーボードの状態、およびマウス ボタンの状態の変更が追跡されます。

  • ユーザーがウィンドウの外に移動すると、DragLeave イベントが発生します。

  • マウスが別のコントロールに入ると、そのコントロールの DragEnter が発生します。

  • マウスが移動しても同じコントロール内に留まった場合、DragOver イベントが発生します。

キーボードまたはマウス ボタンの状態が変化した場合、QueryContinueDrag イベントが発生し、ドラッグを続行するか、データをドロップするか、イベントの QueryContinueDragEventArgsAction プロパティの値に基づいて操作をキャンセルするかを決定します。

  • DragAction の値が Continue場合、操作を続行するために DragOver イベントが発生し、適切な視覚的フィードバックを設定できるように、GiveFeedback イベントが新しい効果で発生します。 有効なドロップ効果の一覧については、DragDropEffects 列挙型を参照してください。

    注意

    DragOver イベントと GiveFeedback イベントはペアになっているため、マウスがドロップ ターゲットを越えて移動すると、ユーザーはマウスの位置に対して最も up-to-date フィードバックを受け取ります。

  • DragAction の値が Drop場合、ドロップ効果の値がソースに返されるため、ソース アプリケーションはソース データに対して適切な操作を実行できます。たとえば、操作が移動の場合はデータを切り取ります。

  • DragAction の値が Cancel場合、DragLeave イベントが発生します。

注意

DoDragDrop メソッドは、すべての例外をキャッチし、次のセキュリティまたは重大な例外のみを再スローします。

  • SecurityException

  • NullReferenceException

  • StackOverflowException

  • OutOfMemoryException

  • ThreadAbortException

  • ExecutionEngineException

  • IndexOutOfRangeException

  • AccessViolationException

こちらもご覧ください

適用対象

.NET Framework 4.8.1 およびその他のバージョン
製品 バージョン
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
Windows Desktop 3.0, 3.1, 5, 6, 7, 8, 9