7

基本的に、サブジェクトのタイムテーブルに似るようにデータグリッドをバインドしました。各行はサブジェクトの学期を表し、その学期内の各セルはサブジェクトを表します。

現在、ドラッグアンドドロップ機能を追加して、追加のサブジェクトをグリッドにドラッグできるようにしようとしています。これにより、基になるデータ構造が更新されます。

いくつかのビジュアルツリーメソッドを使用して、ユーザーが新しいサブジェクトをドラッグしているDataGridCellを見つけることができますが、空白を置き換えるためにセルがバインドされている値(サブジェクト)にアクセスする方法がわかりません/新しい件名のプレースホルダー値。基礎となる値にアクセスする方法はありますか、それともこのプログラムを作成する方法全体を再構築する必要がありますか?

グリッドとその上にドラッグされる被写体の例

4

1 に答える 1

3

ColumnDataGridCell のデータを取得するには、その DataContext とプロパティを使用できます。それを行う方法は、行データが何であるか、つまりItemsSource、DataGrid のコレクションに入れる項目によって異なります。object[]アイテムが配列であると仮定します。

// Assuming this is an array of objects, object[],this gets you the 
// row data as you have them in the DataGrid's ItemsSource collection
var rowData = (object[]) DataGrid.SelectedCells[0].Item;
//  This gets you the single cell object
var celldata = rowData[DataGrid.SelectedCells[0].Column.DisplayIndex];

行データがより複雑な場合は、Columnプロパティと行データ項目を行データ項目の特定の値に変換する適切なメソッドを記述する必要があります。


編集:

データをドロップしたセルが選択されたセルではない場合、1 つのオプションは、以下を使用してデータが属するセルを取得するDataGridRowことDataGridCellですVisualTreeHelper

var parent = VisualTreeHelper.GetParent(gridCell);
while(parent != null && parent.GetType() != typeof(DataGridRow))
{
    parent = VisualTreeHelper.GetParent(parent);
}
var dataRow = parent;

次に、行を取得し、上記のように続行できます。


さらに、メソッドを再考する必要があるかどうかの質問に関しては、カスタムWPF ビヘイビアを使用することをお勧めします。

ビヘイビアーは、XAML ではなく C# コードからコントロールの機能を拡張するための非常に簡単な方法を提供しますが、分離コードを明確かつシンプルに保ちます (これは、MVVM に従っている場合に便利なだけではありません)。動作は、再利用可能で、特定のコントロールにバインドされないように設計されています。

ここに良い紹介があります

あなたの特別なケースのために、私はあなたに何をすべきかについての考えだけを与えることができます:

TextBlock コントロール (または、ドロップを処理する DataGridCells 内に必要な任意のコントロール) 用に1 つ記述します。基本的な考え方は、コントロールのメソッドDropBehavior内のセルのイベントに応じてアクションを登録することです。OnAttached()

public class DropBehavior : Behavior<TextBlock>
{
    protected override void OnAttached()
    {
        AssociatedObject.MouseUp += AssociatedObject_MouseUp;
    }

    private void AssociatedObject_MouseUp(object sender, MouseButtonEventArgs e)
    {
        // Handle what happens on mouse up

        // Check requirements, has data been dragged, etc.
        // Get underlying data, now simply as the DataContext of the AssociatedObject
        var cellData = AssociatedObject.DataContext;

    }
}

行データとColumnプロパティから単一セルのデータを解析することは廃止されることに注意してください。

次に、DataGridContentTemplateのを使用して、この動作をセル内に配置する TextBlocks にアタッチします。CellStyle

<DataGrid>
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="{Binding}">
                            <i:Interaction.Behaviors>
                                <yourns:DropBehavior/>
                            </i:Interaction.Behaviors>
                        </TextBlock>
                    </DataTemplate>
                </Setter.Value>

            </Setter>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

Behavior<T>ベースクラスは次の場所にあります

System.Windows.Interactivity.dll

私はそれをテストしていませんが、うまくいくことを願っています...

于 2013-03-12T13:50:06.267 に答える