サイトアイコン INFRAGISTICS ナレッジ ベース

XamDataGrid レコードのドラッグアンドドロップ

XamDataGrid レコードのドラッグアンドドロップを実装してみましょう。XamDataGrid 単体ではドラッグアンドドロップの機能ありませんが、 Infragistics WPF に含まれる Infragistics Drag and Drop Framework を組み合わせることで実現することができます。

XamDataGrid のレコードは DataRecordPresenter として描画されており、ドラッグアンドドロップ機能を DataRecordPresenter に割り当てていきます。

Snoop を使って XamDataGrid を覗いてみます。DataRecordPresenter はここです。

 

実装の手順

 

1. DataRecordPresenter のテンプレートを取り込む

DataRecordPresenter のテンプレートをアプリケーション内に取り込み、ドラッグアンドドロップ機能を追加して上書きします。テンプレートは下記ファイルパスの DataPresenterGeneric_Express.xaml にあります。

C:\Program Files (x86)\Infragistics\2019.1\WPF\DefaultStyles\DataPresenter
→ DataPresenterGeneric_Express.xaml

 

2. 取り込んだテンプレートのカスタマイズ

DataRecordPresenter の ContentPresenter(x:Name=”PART_RecordContentSite”)に DragDropManager を設定します。DragSource の IsDraggable を True にすることでレコードのドラッグができるようになります。また、DropTarget の IsDropTarget を True にすることでレコードのドロップができるようになります。

続いて、DragSource の Drop イベントをハンドルしてドラッグされたレコードとドロップされた位置を判定してレコード位置の制御を行います。DataRecordPresenter のテンプレートには DragDropBehavior(後述) を設定します。

ここまでの実装内容は下記コードスニペットの 13 – 24 行目と対応します。

<Style TargetType="{x:Type igDP:DataRecordPresenter}">
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type igDP:DataRecordPresenter}">
                <igWindows:CardPanel x:Name="baseGrid" RenderTransform="{TemplateBinding FixedNearElementTransform}" Background="{TemplateBinding Background}">
                    <Border x:Name="addRowFooter" ... />
                    <Grid Margin="0" RenderTransform="{TemplateBinding ScrollableElementTransform}">
                        ...
                        <ContentPresenter x:Name="PART_RecordContentSite" ...>

                            <!--ドラッグアンドドロップの設定-->
                            <ig:DragDropManager.DragSource>
                                <ig:DragSource  IsDraggable="True">
                                    <i:Interaction.Behaviors>
                                        <!--ビヘイビアの設定-->
                                        <behaviors:DragDropBehavior/>
                                    </i:Interaction.Behaviors>
                                </ig:DragSource>
                            </ig:DragDropManager.DragSource>

                            <ig:DragDropManager.DropTarget>
                                <ig:DropTarget IsDropTarget="True"/>
                            </ig:DragDropManager.DropTarget>
                            <!--ドラッグアンドドロップの設定-->

                        </ContentPresenter>
                        ...
                    </Grid>
                </igWindows:CardPanel>
                ...
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    ...
</Style>

 

3. DragDropBehavior の実装

次に、DragDropBehavior に DragSource のレコードがドロップされたタイミングで発生する Drop イベントを実装していきます。

public class DragDropBehavior : Behavior<DragSource>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.Drop += AssociatedObject_Drop;
    }

    private void AssociatedObject_Drop(object sender, DropEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Drop");

        DragSource dragSource = sender as DragSource;
        FrameworkElement fe = dragSource.AssociatedObject as FrameworkElement;
        Record record = fe.DataContext as Record;

        // XamDataGrid の取得
        XamDataGrid presenter = record.DataPresenter as XamDataGrid;

        // ドラッグレコードの取得
        ContentPresenter source = e.DragSource as ContentPresenter;
        DataRecord sourceRecord = source.DataContext as DataRecord;
        int sourceIndex = sourceRecord.Index;

        // ドロップレコードの取得
        ContentPresenter target = e.DropTarget as ContentPresenter;
        DataRecord targetRecord = target.DataContext as DataRecord;
        int targetIndex = targetRecord.Index;

        var dc = presenter.DataContext;
        MainViewModel vm = dc as MainViewModel;

        // ドラッグレコードの位置変更
        vm.Tasks.Move(sourceIndex, targetIndex);
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.Drop -= AssociatedObject_Drop;
        base.OnDetaching();
    }
}

 

 

実行結果

レコードのドラッグアンドドロップができるようになりました。

 

サンプル

 

オンラインリソース

DataRecordPresenter クラス https://jp.infragistics.com/help/wpf/infragisticswpf.datapresenter~infragistics.windows.datapresenter.datarecordpresenter

Infragistics Drag and Drop Framework
https://jp.infragistics.com/help/wpf/drag-and-drop-framework

モバイルバージョンを終了