Drag and Drop allow reorder but disallow removal

5 posts, 0 answers
  1. Rob
    Rob avatar
    10 posts
    Member since:
    Nov 2012

    Posted 14 Feb 2013 Link to this post

    Attached is a simple project (actually no it's not because apparently I can't attach a zip file - the MainPage.xaml/xaml.cs are pasted below) with two RadListBoxes that have drag and drop enabled on them. Can someone please explain how I can prevent the items from being removed from their respective lists. That is I want to be able the reorder a list but not share the items between the two lists or any other control.

    This is just a proof of concept, I have a 1 RadListBox in another project that I need to be able to reorder but I don't want users to be able to remove the items from the list. The RadListBox appears in a RadSplitButton drop down panel which happens to drop down over a RadGridView, I've set AllowDrop="false" on the grid but it hasn't help I can still drop the items from the list onto the Grid and then they just evaporate into the ether. Plus! I don't want to have to disable "Drop" on every other control to prevent a user removing the item from the list.


    <UserControl x:Class="RadListBoxDragAndDropPOC.MainPage"
            mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
            DataContext="{Binding RelativeSource={RelativeSource self}}"
            x:Name="Page">
     
     
        <UserControl.Resources>
            <Style x:Key="DraggableListBoxItem" TargetType="telerik:RadListBoxItem">
                <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
            </Style>
        </UserControl.Resources>
         
        <Grid x:Name="LayoutRoot">
     
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
            </Grid.ColumnDefinitions>
     
            <telerik:HeaderedContentControl Grid.Column="0">
     
                    <telerik:RadListBox ItemsSource="{Binding Path=DataContext.MockDataList, ElementName=Page}"
                                        HorizontalAlignment="Stretch"
                                        VerticalAlignment="Stretch"
                                        ItemContainerStyle="{StaticResource DraggableListBoxItem}" AllowDrop="False">
                        <telerik:RadListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <TextBlock Text="{Binding DisplayName}" />
                                </StackPanel>
                            </DataTemplate>
                        </telerik:RadListBox.ItemTemplate>
                        <telerik:RadListBox.DragVisualProvider>
                            <telerik:ScreenshotDragVisualProvider />
                        </telerik:RadListBox.DragVisualProvider>
                        <telerik:RadListBox.DragDropBehavior>
                            <telerik:ListBoxDragDropBehavior AllowReorder="True" />
                        </telerik:RadListBox.DragDropBehavior>
                    </telerik:RadListBox>
     
            </telerik:HeaderedContentControl>
     
            <telerik:HeaderedContentControl Grid.Column="1">
     
                <telerik:RadListBox ItemsSource="{Binding Path=DataContext.MockDataListTwo, ElementName=Page}"
                                        HorizontalAlignment="Stretch"
                                        VerticalAlignment="Stretch"
                                        ItemContainerStyle="{StaticResource DraggableListBoxItem}">
                    <telerik:RadListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </telerik:RadListBox.ItemTemplate>
                    <telerik:RadListBox.DragVisualProvider>
                        <telerik:ScreenshotDragVisualProvider />
                    </telerik:RadListBox.DragVisualProvider>
                    <telerik:RadListBox.DragDropBehavior>
                        <telerik:ListBoxDragDropBehavior AllowReorder="True" />
                    </telerik:RadListBox.DragDropBehavior>
                </telerik:RadListBox>
     
            </telerik:HeaderedContentControl>
     
     
        </Grid>
    </UserControl>



    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
     
    namespace RadListBoxDragAndDropPOC
    {
        public partial class MainPage : UserControl
        {
     
     
            public ObservableCollection<MockData> MockDataList
            {
                get { return (ObservableCollection<MockData>)GetValue(MockDataListProperty); }
                set { SetValue(MockDataListProperty, value); }
            }
     
            // Using a DependencyProperty as the backing store for MockDataList.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty MockDataListProperty =
                DependencyProperty.Register("MockDataList", typeof(ObservableCollection<MockData>), typeof(MainPage), new PropertyMetadata(null));
     
     
     
     
            public ObservableCollection<MockData> MockDataListTwo
            {
                get { return (ObservableCollection<MockData>)GetValue(MockDataListTwoProperty); }
                set { SetValue(MockDataListTwoProperty, value); }
            }
     
            // Using a DependencyProperty as the backing store for MockDataListTwo.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty MockDataListTwoProperty =
                DependencyProperty.Register("MockDataListTwo", typeof(ObservableCollection<MockData>), typeof(MainPage), new PropertyMetadata(null));
     
     
            public MainPage()
            {
                InitializeComponent();
     
                List<MockData> mockDataList = new List<MockData>();
     
                mockDataList.Add(new MockData("One", 1));
                mockDataList.Add(new MockData("Two", 2));
                mockDataList.Add(new MockData("Three", 3));
                mockDataList.Add(new MockData("Four", 4));
                mockDataList.Add(new MockData("Five", 5));
                mockDataList.Add(new MockData("Six", 6));
                mockDataList.Add(new MockData("Seven", 7));
     
                this.MockDataList = new ObservableCollection<MockData>(mockDataList);
     
                List<MockData> mockDataList2 = new List<MockData>();
     
                mockDataList2.Add(new MockData("2One", 1));
                mockDataList2.Add(new MockData("2Two", 2));
                mockDataList2.Add(new MockData("2Three", 3));
                mockDataList2.Add(new MockData("2Four", 4));
                mockDataList2.Add(new MockData("2Five", 5));
                mockDataList2.Add(new MockData("2Six", 6));
                mockDataList2.Add(new MockData("2Seven", 7));
     
                this.MockDataListTwo = new ObservableCollection<MockData>(mockDataList2);
            }
        }
     
        public class MockData
        {
            public string DisplayName { get; set; }
            public int DisplayOrder { get; set; }
     
            public MockData(string displayName, int displayOrder)
            {
                this.DisplayName = displayName;
                this.DisplayOrder = displayOrder;
            }
        }
    }
  2. Rob
    Rob avatar
    10 posts
    Member since:
    Nov 2012

    Posted 17 Feb 2013 Link to this post

    I've worked this out after many hours and as usual the answer is easy when you know how (I must say the documentation for Drag Drop is terrible Telerik and many Google searches return deprecated solutions)

    All I needed to do was create a custom DragDropBehavior like so:

    namespace RadListBoxDragAndDropPOC
    {
        public class RadListBoxCustomDragDropBehavior : Telerik.Windows.DragDrop.Behaviors.ListBoxDragDropBehavior
        {
            public override bool CanDrop(Telerik.Windows.DragDrop.Behaviors.DragDropState state)
            {
                return state.IsSameControl;
            }
        }
    }

    And then change this in my xaml:

    <telerik:RadListBox.DragDropBehavior>
          <dragDrop:RadListBoxCustomDragDropBehavior AllowReorder="True" />
    </telerik:RadListBox.DragDropBehavior>
  3. DevCraft banner
  4. Mark
    Mark avatar
    1 posts
    Member since:
    Sep 2011

    Posted 18 Nov 2014 in reply to Rob Link to this post

    I know this is a couple years old, but thank you! Your solution worked quite well and saved me a lot of time after coming up empty on the WPF documentation.
  5. Terry
    Terry avatar
    17 posts
    Member since:
    Mar 2013

    Posted 10 Mar Link to this post

    I would love this to be the answer to my issue as I am having the exact same problem. Unfortunately, the items are still removed from my RadListBox when dragging away from the list box after implementing this solution.

    Any ideas why?

    I'm using Telerik_UI_for_WPF_2014_1_331

  6. Terry
    Terry avatar
    17 posts
    Member since:
    Mar 2013

    Posted 10 Mar in reply to Terry Link to this post

    Found the right answer here: http://www.telerik.com/forums/radlistbox-drag-and-drop-without-removing-dropped-item
Back to Top
DevCraft banner