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