How can I access a DataGridCell data object in code?

I basically tied the datagrid so that it resembled a topic schedule - each row represents a semester of subjects, and each cell in this semester represents a topic.

Now I am trying to add drag and drop functionality so that you can drag additional objects into the grid and this will update the underlying data structure.

I can use some visual tree-like methods to find a DataGridCell to which the user is dragging a new object, but I don’t know how to access the value (subject) to which the cell is bound to replace the blank / placeholder value with the new object. Is there a way to access the base value or do I need to rebuild my entire method of creating this program?

An example of the grid and the subjects to be dragged onto it

+7
source share
1 answer

To get DataGridCell data, you can use its DataContext and Column property. How to do this, it exactly depends on the data of your string, i.e. What items do you put in the ItemsSource DataGrid collection. Assuming your elements are object[] arrays:

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

If your data in a row is more complex, you need to write an appropriate method that converts the Column property and row data element to a specific value in the row data element.


EDIT:

If the cell you are dropping data into is not the selected cell, one of them is to get the DataGridRow to which the DataGridCell belongs, using VisualTreeHelper :

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

Then you have a line and can act as above.


Also, regarding your question about whether to revise the method, I would suggest using WPF custom behavior.

Behavior provides a very direct way to expand the control capabilities from C # code, not XAML, but at the same time your code is easy and simple (which is not only nice if you follow MVVM). Behaviors are designed to be reusable and not tied to your specific control.

Here is a good introduction

In your specific case, I can only give you an idea of ​​what to do:

Write one DropBehavior for your TextBlock control (or any other control that you want to use in your DataGridCells that handles the drop. The main idea is to register actions performed by evnt cells in the OnAttached() method of your control.

 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; } } 

Note that parsing single cell data from row data and the Column property is becoming obsolete.

Then you attach this behavior to the TextBlocks that you put in your cells using the ContentTemplate CellStyle your DataGrid:

 <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> 

Bactex Behavior<T> can be found in

System.Windows.Interactivity.dll

I have not tested it, but I hope this works for you and you get the idea ...

+3
source

All Articles