Drag and drop between ItemsControl and Datagrid

17 posts, 0 answers
  1. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 17 Feb 2014 Link to this post

    Hi,

    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>
  2. Rosen Vladimirov
    Admin
    Rosen Vladimirov avatar
    640 posts

    Posted 18 Feb 2014 Link to this post

    Hi Jiri,

    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
  3. DevCraft banner
  4. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 18 Feb 2014 in reply to Rosen Vladimirov Link to this post

    Hi Rosen,

    Great, thank you, it's now clear.

    Regards,

    Tomas
  5. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 14 Apr 2014 Link to this post

    Hi Rosen,

    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
  6. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 15 Apr 2014 in reply to Jiri Link to this post

    PS: Try rather more - 64 rows, for better effect...
  7. Rosen Vladimirov
    Admin
    Rosen Vladimirov avatar
    640 posts

    Posted 16 Apr 2014 Link to this post

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

     
  8. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 17 Apr 2014 in reply to Rosen Vladimirov Link to this post

    Hi Rosen,

    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
  9. Rosen Vladimirov
    Admin
    Rosen Vladimirov avatar
    640 posts

    Posted 17 Apr 2014 Link to this post

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

     
  10. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 09 Apr 2015 in reply to Rosen Vladimirov Link to this post

    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

  11. Kalin
    Admin
    Kalin avatar
    1207 posts

    Posted 14 Apr 2015 Link to this post

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

     
  12. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 21 Apr 2015 in reply to Kalin Link to this post

    Hi Kalin,

    Sorry for late answer, but thank you, this is OK.

    Cheers,

    Jiri

  13. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 12 Oct 2015 Link to this post

    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

  14. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 12 Oct 2015 in reply to Jiri Link to this post

    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

  15. Kalin
    Admin
    Kalin avatar
    1207 posts

    Posted 13 Oct 2015 Link to this post

    Hi 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
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  16. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 13 Oct 2015 Link to this post

    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

  17. Kalin
    Admin
    Kalin avatar
    1207 posts

    Posted 15 Oct 2015 Link to this post

    Hello 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
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  18. Jiri
    Jiri avatar
    40 posts
    Member since:
    Oct 2013

    Posted 16 Oct 2015 in reply to Kalin Link to this post

    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

Back to Top
DevCraft banner