SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ComponentZine(ComponentOne)

ドラッグ&ドロップで操作できるシフト表作成WPFアプリケーションを作る

ComponentOne Studioを活用したWindowsフォームアプリケーションの作成

  • このエントリーをはてなブックマークに追加

ドラッグ処理の作成

 実際にテキストブロックをドラッグできるようにする処理は、ビハインドコードで作成します。

テキストブロックのドラッグ処理

 テキストブロックのドラッグ処理は、C1DragDropManagerクラスのRegisterDropTargetメソッドを呼び出して、グリッドがドロップ先になるように指定します。

 次に、RegisterDragSourceメソッドを使用してドラッグ元にテキストブロックを指定します。

 そして、マウス座標をグリッドの座標に変換するイベントハンドラを作成し、DragDropイベントに連結します。

 これで、テキストブロックをドラッグすると、グリッドの新しい位置に移動できるようになります。

 ① 最初に、C1DragDropManagerクラスのインスタンスを作成します。

 そして、RegisterDropTargetメソッドの引数にGrid要素を指定し、グリッドをドロップ先になるように指定します。

 RegisterDropTargetメソッドは2つの引数を持ち、一つはドロップ先として機能するUIElementオブジェクト、もう一つは要素を登録する場合はtrue、登録解除する場合はfalseの論理値を指定します。

Visual Basic
Imports C1.WPF
Class MainWindow
    Public Sub New()

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。

        'ドラッグドロップ マネージャの作成
        Dim ddmgr As New C1DragDropManager()
        ddmgr.RegisterDropTarget(Grid1, True)
C#
using C1.WPF;
namespace DragDropMNG_WPF_cs
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            C1DragDropManager ddmng = new C1DragDropManager();
            ddmng.RegisterDropTarget(Grid1, true);

 ② 続いて、RegisterDragSourceメソッドを使用してテキストブロックをドラッグ対象のオブジェクトとして指定します。グリッド上にいくつテキストブロックがあってもドラッグ対象に設定できるように、グリッド内のオブジェクトを一つ一つサーチしドラッグ対象として設定していきます。

 RegisterDragSourceメソッドは3つの引数を持ち、1つはドラッグ対象のUIElementオブジェクト、もう一つはドラッグ元をドロップ先要素にドロップしたときに実行されるアクションが、移動なのかコピーなのかを表すをDragDropEffect列挙体のメンバで指定します。

 3つ目の引数は、どの修飾子キー(Shiftキー、CtrlキーおよびAltキー)が押された状態であるかを示す値を格納しているModifierKeysプロパティ(Controlクラスのメンバ値はKeys列挙体メンバ)を指定しますが、このメソッドではデフォルトの「None」を指定します。

DragDropEffect列挙体のメンバ
メンバ名 説明
None アクションなし
Move ドラッグ元要素をドラッグ先要素に移動します
Copy ドラッグ元要素をドラッグ先要素にコピーします
Visual Basic
For Each e As UIElement In Grid1.Children
    ddmgr.RegisterDragSource(e, DragDropEffect.Move, ModifierKeys.None)
Next
C#
foreach (UIElement e in Grid1.Children)
{
    ddmng.RegisterDragSource(e, DragDropEffect.Move, ModifierKeys.None);
}

 ③ そして、C1DragDropManagerクラスのDragDropイベントに、マウス座標をグリッドの座標に変換するイベントハンドラ「Do_DragDrop」を連結します。

Visual Basic
    AddHandler ddmgr.DragDrop, AddressOf Do_DragDrop
End Sub
C#
    ddmng.DragDrop += Do_DragDrop;
}

座標変換用イベントハンドラ「Do_DragDrop」の作成

 C1DragDropManagerコンポーネントの設定が終わったら、マウス座標をグリッドの座標に変換するイベントハンドラ「Do_DragDrop」を作成します。

 DragDropイベントは、ドラッグ&ドロップ処理の最後に、ユーザーが登録されたドロップ先上でマウスボタンを放したときに発生します。

 そこで、グリッドのどの位置にドロップされたのかをマウスの位置で判断し、そこにテキストブロックを移動させます。

 ① まずマウスボタンがクリックされた位置を取得します。そして、その値からグリッドの行列番号を導き出します。

 これは、グリッドの行列の高さと幅を計算して割り出します。

Visual Basic
Private Sub Do_DragDrop(source As Object, e As DragDropEventArgs)

    ' マウスの位置を取得
    Dim MousePt As Point = e.GetPosition(Grid1)

    ' グリッド行/列座標に変換
    Dim row As Integer, col As Integer
    Dim GridPt As New Point(0, 0)
    For row = 0 To Grid1.RowDefinitions.Count - 1
        GridPt.Y += Grid1.RowDefinitions(row).ActualHeight
        If GridPt.Y > MousePt.Y Then
            Exit For
        End If
    Next

    For col = 0 To Grid1.ColumnDefinitions.Count - 1
        GridPt.X += Grid1.ColumnDefinitions(col).ActualWidth
        If GridPt.X > MousePt.X Then
            Exit For
        End If
    Next
C#
private void Do_DragDrop(object source, DragDropEventArgs e)
{
    // マウスの位置を取得
    Point MousePt = e.GetPosition(Grid1);
    // グリッド行/列座標に変換
    int row, col;
    Point GridPt = new Point(0, 0);
    for (row = 0; row < Grid1.RowDefinitions.Count; row++)
    {
        GridPt.Y += Grid1.RowDefinitions[row].ActualHeight;
        if (GridPt.Y > MousePt.Y)
        break;
    }
    for (col = 0; col < Grid1.ColumnDefinitions.Count; col++)
    {
        GridPt.X += Grid1.ColumnDefinitions[col].ActualWidth;
        if (GridPt.X > MousePt.X)
        break;
    }

 ② ドロップ先のグリッドの位置が決まったら、テキストブロックを移動させます。

 まず、イベントハンドラの引数「DragDropEventArgs」クラスのDragSourceプロパティでドラッグ元のUIElementオブジェクトを取得します。この場合はテキストブロックなので、TextBlockクラスのSetValueメソッドを使用して移動させます。

 SetValueメソッドは依存関係プロパティ識別子を指定して、依存関係プロパティのローカル値を設定するメソッドです。この場合、TextBlock要素はGrid要素の子要素として依存関係にあるので、グリッドの行列番号を指定することでその位置のグリッドにテキストブロックが移動するようになります。

Visual Basic
' 要素を新しい位置に移動
e.DragSource.SetValue(Grid.RowProperty, row)
e.DragSource.SetValue(Grid.ColumnProperty, col)
C#
// 要素を新しい位置に移動
e.DragSource.SetValue(Grid.RowProperty, row);
e.DragSource.SetValue(Grid.ColumnProperty, col);

 以上で出来上がりです。

まとめ

 ドラッグ&ドロップ機能は、使い方によってはユーザーの操作性を高めてくれる便利な機能です。特にWPFアプリケーションでは、タブレット端末も視野に入れてアプリケーションを開発することもあります。アプリケーションの機能の中にドラッグ&ドロップを組み込むのであれば、C1DragDropManagerコンポーネントはきっと役に立つでしょう。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
ComponentZine(ComponentOne)連載記事一覧

もっと読む

この記事の著者

瀬戸 遥(セト ハルカ)

8ビットコンピュータの時代からBASICを使い、C言語を独習で学びWindows 3.1のフリーソフトを作成、NiftyServeのフォーラムなどで配布。Excel VBAとVisual Basic関連の解説書を中心に現在まで40冊以上の書籍を出版。近著に、「ExcelユーザーのためのAccess再...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7560 2013/12/25 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング