I have this scenario: I have a 2D matrix created by two ItemControls, one is outer for rows, second is a nested and it represent the columns of each row. All it represent a bus seat plan.
Next I have a DataGrid of people and I need to drag & drop items - people between the DataGrid and the ItemsControl matrix.
Is it possible using DragDropBehavior? How to set it?
Thank you
Here is how looks my matrix, the SeatPlan is ObservableCollection<ObservableCollection<Seat>>:
<
ItemsControl
ItemsSource
=
"{Binding SeatPlan}"
>
<
ItemsControl.ItemsPanel
>
<
ItemsPanelTemplate
>
<
StackPanel
Orientation
=
"Vertical"
>
</
StackPanel
>
</
ItemsPanelTemplate
>
</
ItemsControl.ItemsPanel
>
<
ItemsControl.ItemTemplate
>
<
DataTemplate
>
<
ItemsControl
ItemsSource
=
"{Binding}"
>
<
ItemsControl.ItemsPanel
>
<
ItemsPanelTemplate
>
<
StackPanel
Orientation
=
"Horizontal"
>
</
StackPanel
>
</
ItemsPanelTemplate
>
</
ItemsControl.ItemsPanel
>
<
ItemsControl.ItemTemplate
>
<
DataTemplate
>
<
Grid
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"30"
/>
<
ColumnDefinition
Width
=
"*"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
TextBox
Grid.Column
=
"0"
Text
=
"{Binding Label, Mode=TwoWay}"
/>
<
TextBox
Grid.Column
=
"1"
Text
=
"{Binding Descr, Mode=TwoWay}"
/>
</
Grid
>
</
DataTemplate
>
</
ItemsControl.ItemTemplate
>
</
ItemsControl
>
</
DataTemplate
>
</
ItemsControl.ItemTemplate
>
</
ItemsControl
>
16 Answers, 1 is accepted
In order to achieve the desired functionality, you can use DragDropManager and the following events:
- add DragInitialize handler for your GridViewRows - this event is raised when DragOperation is started. In it you have to set the information that will be transferred.
- add Drop handler for your Grid inside the inner ItemsControl. This way you will be able to handle Drop operation and to use the data that is transferred via the drag-drop operation.
I've prepared a sample project demonstrating the above approach. I've created two behaviors - DataGridRowDragHelper that is used to handle drag operations for DataGridRow and GridPanelDropHelper, which is used to handle drop operation inside ItemsControl.
Please check the attached project and inform us in case you have any problems or concerns.
Regards,
Rosen Vladimirov
Telerik

Great, thank you, it's now clear.
Regards,
Tomas

I have found out some performance issues after some time. You can see it when change the number of columns and rows in your sample to for example 8 cols and 16 rows. After that you will see a really slow motion of mouse cursor when dragging over ItemsControl.
Could you please take a look at this and let me know?
Thank you,
Jiri

The problem is caused by the StackPanel's that are used for ItemsPanel of the two ItemsControl. By default the ItemsControl is not virtualized and using StackPanel is making the UI even slower. I recommend you to use RadListBox, and set its ItemsPanel to VirtualizingStackPanel. This way you will get all the benefits of the virtualization and you will have much better performance.
I've modified my sample project to show the above approach. Please give it a try and inform us in case you have any problems or concerns.
Regards,
Rosen Vladimirov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

Yes RadListBox with VirtualizingStackPanel works well.
But my problem is now that I am using Grid for row items instead of StackPanel. So do you have any hint in this situation? That Grid is used for better layout when user changes width of the form, the TextBoxes with names are changing their width too.
Thank you,
Jiri
I've created my project based on your code that you've sent in your first post. The idea here is to use panels that are not measured with infinity, for example if you have Grid with ColumnWidth (Row height) set to Auto, it will be measured with infinity and this will make your UI operations slower. Also StackPanel that doesn't have Width and Height set is measured with infinity.
You can use the panels you need, just be careful for the above mentioned scenarios. If you have any further issues, please send us the exact code of your 2D matrix, so we could provide better help.
Hope this helps.
Regards,
Rosen Vladimirov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

Hi,
I would have one additional question: How to modify your solution to be able drag and drop multiple selected rows from DataGrid?
Thanks in advance,
Jiri
You would be able to drag multiple selected rows by adding DragInitializeHandler to the whole DataGrid instead of each row and simply put the SelectedItems in the drag drop payload. However when using the DataGrid you would need to keep the Ctrl or Shift press when start the dragging operation in order to keep the selection correct. If you don't like that behavior you can use our RadGridView instead of the DataGrid and everything should work as expected.
Hope this helps.
Regards,
Kalin
Telerik
See What's Next in App Development. Register for TelerikNEXT.

Hi Kalin,
Sorry for late answer, but thank you, this is OK.
Cheers,
Jiri

Hi,
I would like to connect to last answer from Kalin.
I have converted our SL project to WPF and now I have found out that the above mentioned D&D operation with multiple rows doesn't work properly. It was OK to do that operation with ctrl or shift key pressed in Silverlight as Kalin mentioned, but there is now problem with it in WPF. It is obviously caused by different behavior of Extended selection mode in WPF's DataGrid, where it is possible to select multiple rows only by using mouse - without the shift key pressed. In WPF it is now needed to select rows first and then release mouse button and shift key and only then perform drag operation. And I would be quite satisfied even with this method, but it doesn't work in case of selecting with ctrl key.
So would you have any workaround in this situation? I don't want to use RadGridView because we are using our own improved DataGrid with a lot of additional functionality throughout whole application.
Thank you,
Jiri

Hi,
I would like to connect to last answer from Kalin.
I have converted our SL project to WPF and now I have found out that the above mentioned D&D operation with multiple rows doesn't work properly. It was OK to do that operation with ctrl or shift key pressed in Silverlight as Kalin mentioned, but there is now problem with it in WPF. It is obviously caused by different behavior of Extended selection mode in WPF's DataGrid, where it is possible to select multiple rows only by using mouse - without the shift key pressed. In WPF it is now needed to select rows first and then release mouse button and shift key and only then perform drag operation. And I would be quite satisfied even with this method, but it doesn't work in case of selecting with ctrl key.
So would you have any workaround in this situation? I don't want to use RadGridView because we are using our own improved DataGrid with a lot of additional functionality throughout whole application.
Thank you,
Jiri
What I can suggest you would be to check the following thread for a possible solution:
http://stackoverflow.com/questions/25097750/wpf-datagrid-multiple-selection-is-lost-on-drag
However please note this is a framework behavior and might not be possible to get it working perfectly.
Hope this will help you.
Regards,
Kalin
Telerik

Hi Kalin,
Thank you for this suggestion, but unfortunately that SO solution doesn't work for me. Did you try it? I would say it is attempt of switching off the selecting of rows when mouse move with left button pressed. And I would say it is right direction.
Interestingly though, the handler set by DragDropManager.AddDragInitializeHandler catches in one case which I described above - how is it done?. So perhaps there exist some combination of events to make this sloppy microsoft design using only mouse stop work and make it work only with combination of shift and ctrl keys.
What do you think next?
Thank you,
Jiri
You can try hooking to the MouseMove event of the DataGrid and implementing the following handler:
private
void
PeopleGrid_MouseMove(
object
sender, MouseEventArgs e)
{
if
(e.LeftButton == MouseButtonState.Pressed &&
Keyboard.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift) &&
this
.PeopleGrid.SelectedItems.Count > 0)
{
var data =
this
.PeopleGrid.SelectedItems.Cast<Person>().ToList();
var dragVisual =
new
DragVisual()
{
Content = data,
ContentTemplate = Application.Current.Resources[
"DragVisualTemplate"
]
as
DataTemplate,
};
DragDropManager.DoDragDrop(
this
.PeopleGrid, data, DragDropEffects.All, DragDropKeyStates.None, dragVisual,
new
Point(),
new
Point());
e.Handled =
true
;
}
}
This will perform drag operation whenever Ctrl and Shift keys are pressed.
Hope this will work for you.
Regards,
Kalin
Telerik

Hi Kalin,
Great! This is it!
Only that condition should be with this: (Keyboard.Modifiers == ModifierKeys.Control || Keyboard.Modifiers == ModifierKeys.Shift)
Thank you very much,
Jiri