Drag&Drop on read-only collection

4 posts, 1 answers
  1. Daniel
    Daniel avatar
    23 posts
    Member since:
    May 2009

    Posted 28 Nov 2012 Link to this post

    Hi,

    I have stantard MVVM scenario, when I exposed ReadOnlyObservableCollection as a public property on my ViewModel. I add or remove items by commands, because it involves additional domain logic. I dont want to make the source collection public to ensure consistency of my model.

    In treeview I solved it nicely with PreviewDragEnded="RadTreeView_PreviewDragEnded"
    How to do it with RadListBox?

    Thanks.
    Daniel 
  2. Vladi
    Admin
    Vladi avatar
    744 posts

    Posted 03 Dec 2012 Link to this post

    Hi Daniel,

    We are not sure we understand you correctly.

    Could you explain to us in more details the scenario in your project and what do you use the Drag and Drop functionality on the readonly collection for?

    Greetings,
    Vladi
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. UI for WPF is Visual Studio 2017 Ready
  4. Daniel
    Daniel avatar
    23 posts
    Member since:
    May 2009

    Posted 03 Dec 2012 Link to this post

    Ok, maybe as a programmer I could better express my toughts by code :)

    public class MainViewModel
    {
       private ResourceFile resourceFile; //COM object
       private readonly ObservableCollection<ResourceVM> _Resources = new ObservableCollection<ResourceVM>();
     
       public ReadOnlyObservableCollection<ResourceVM> Resources { get; private set; }
     
     
       public MainViewModel()
       {
          ...
         Resources = new ReadOnlyObservableCollection(_Resources);
       }
     
       public void InsertResource(ResourceVM resource, int index = 0)
       {
          //custom logic insert here:
          Resource comResourceObject = resourceVM.ComResourceObject;
          resourceFile.Resources.Add(comResourceObject )  
     
          _Resources.Insert(index, resource);
       }
     
      public void RemoveResource(ResourceVM resource)
      {
        ...
      }
    }



    The ObservableCollection is private, because everytime I make changes to it I need to run some custom logic.

    I would like to use reorder feature of RadListBox. My suggestion is to add events (DragStarted, DragEnded, PreviewDragStarted, PreviewDragEnded) to the ListBoxDragDropBehaviour. It would be very simillar to RadTreeView built in drag&drop.

    In my case I would solve my issue like this:

    <telerik:RadListBox ItemsSource="{Binding Resources}">
      <telerik:RadListBox.ItemContainerStyle>
        <Style TargetType="telerik:RadListBoxItem" BasedOn="{StaticResource RadListBoxItemStyle}">
          <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
        </Style>
      </telerik:RadListBox.ItemContainerStyle>
      <telerik:RadListBox.DragDropBehavior>
        <telerik:ListBoxDragDropBehavior AllowReorder="True" PreviewDragEnded="RadListBox_PreviewDragEnded" />
      </telerik:RadListBox.DragDropBehavior>

     

    RadDistBox_PreviewDragEnded(object sender, DragEndedEventArgs e)
    {
      e.Handled = true;
      var resource = ((FrameworkElement)sender).DataContext as ResourceVM;
      ViewModel.RemoveResource(resource)
      ViewMOdel.AddResource(resource, e.NewIndex);
    }


    Of couse, if you have better solution, I'm all in.

    Maybe the events in DragDropManager could help...

  5. Answer
    Vladi
    Admin
    Vladi avatar
    744 posts

    Posted 06 Dec 2012 Link to this post

    Hello Daniel,

    In order to add custom logic when an item has been dropped in the ListBox control you will need to customize the DragDropBehavior of the control by creating a class that inherits ListBoxDragDropBehavior and override its Drop() method which is triggered when item has been dropped in the control and DragDropCompleted() method which is triggered when an item has been dragged from the control and dropped in another one.

    The custom ListBoxDragDropBehavior should look something like this:
    public class CustomListBoxDragDropBehavior : ListBoxDragDropBehavior
    {
        public override void Drop(DragDropState state)
        {
            // Custom logic when item is dropped in the control
            base.Drop(state);
        }
     
        public override void DragDropCompleted(DragDropState state)
        {
            // Custom logic when item is dragged and dropped from the control
            base.DragDropCompleted(state);
        }
    }

    Hope this is helpful.

    All the best,
    Vladi
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top