Drag And Drop to RadGridView Header row

7 posts, 1 answers
  1. Michal
    Michal avatar
    11 posts
    Member since:
    Jul 2014

    Posted 09 Dec 2014 Link to this post

    I have a ListBox and RadGridView and I'm trying to implement Drag And Drop between list items and grid rows and vice versa.
    This is for testing purposes and I'm trying to test raising and capturing Drop and DragCompleted events on all RadGridView parts.
    Everything works fine except drop to a Header Row of a RadGridView. Drop and DragCompleted is not raised and also DragVisual shows that you can't drop to  a Header Row of a RadGridView. I guess this is a default behavior of RadGridView and I would like to ask if there is any way or workaround how to drop to a Header Row of a RadGridView? I need this feature for a WPF application in my work.

    here is my xaml

    <Window x:Class="DragDropManager.MainWindow"
            Title="MainWindow" >
        <Grid x:Name="LayoutRoot" Background="White">
            <Grid.Resources>
                <Style TargetType="ListBoxItem">
                    <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True"></Setter>
                </Style>
                <DataTemplate x:Key="ApplicationTemplate">
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding IconPath}"/>
                        <TextBlock Margin="5" Text="{Binding Name}" VerticalAlignment="Center"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </Grid.Resources>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <ListBox x:Name="ApplicationList" ItemTemplate="{StaticResource ApplicationTemplate}" AllowDrop="True"/>
            <telerik:RadGridView Grid.Column="1" AllowDrop="True" x:Name="MyGrid">
                <telerik:RadGridView.RowStyle>
                    <Style TargetType="telerik:GridViewRow">
                        <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
                    </Style>
                </telerik:RadGridView.RowStyle>
            </telerik:RadGridView>
        </Grid>
    </Window>

    and here is my code behind

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ApplicationList.ItemsSource = ApplicationInfo.GenerateApplicationInfos();
            MyGrid.ItemsSource = new ObservableCollection<ApplicationInfo>();
     
            Telerik.Windows.DragDrop.DragDropManager.AddDragInitializeHandler(ApplicationList, OnDragInitialize);
            Telerik.Windows.DragDrop.DragDropManager.AddDragInitializeHandler(MyGrid, OnDragInitialize);
     
            Telerik.Windows.DragDrop.DragDropManager.AddGiveFeedbackHandler(ApplicationList, OnGiveFeedback);
            Telerik.Windows.DragDrop.DragDropManager.AddGiveFeedbackHandler(MyGrid, OnGiveFeedback);
     
            Telerik.Windows.DragDrop.DragDropManager.AddDragDropCompletedHandler(ApplicationList, OnDragCompleted);
            Telerik.Windows.DragDrop.DragDropManager.AddDragDropCompletedHandler(MyGrid, OnDragCompleted2);
     
            Telerik.Windows.DragDrop.DragDropManager.AddDropHandler(ApplicationList, OnDrop);
            Telerik.Windows.DragDrop.DragDropManager.AddDropHandler(MyGrid, OnDrop2);
        }
     
        private void OnDragInitialize(object sender, DragInitializeEventArgs args)
        {
            args.AllowedEffects = DragDropEffects.All;
            var payload = DragDropPayloadManager.GeneratePayload(null);
            var data = ((FrameworkElement)args.OriginalSource).DataContext;
            payload.SetData("DragData", data);
            args.Data = payload;
            args.DragVisual = new DragVisual() { Content = data, ContentTemplate = LayoutRoot.Resources["ApplicationTemplate"] as DataTemplate };
            args.DragVisualOffset = args.RelativeStartPoint;
            args.Handled = true;
        }
     
        private void OnGiveFeedback(object sender, Telerik.Windows.DragDrop.GiveFeedbackEventArgs args)
        {
            args.SetCursor(Cursors.Arrow);
            args.Handled = true;
        }
     
        private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs args)
        {
            var data = ((DataObject)args.Data).GetData("DragData");
            ((IList)(sender as ListBox).ItemsSource).Add(data);
        }
     
        public void OnDragCompleted(object sender, Telerik.Windows.DragDrop.DragDropCompletedEventArgs args)
        {
            var data = DragDropPayloadManager.GetDataFromObject(args.Data, "DragData");
            ((IList)(sender as ListBox).ItemsSource).Remove(data);
        }
     
        private void OnDrop2(object sender, Telerik.Windows.DragDrop.DragEventArgs args)
        {
            var data = ((DataObject)args.Data).GetData("DragData");
            ((IList)(sender as RadGridView).ItemsSource).Add(data);
        }
     
        public void OnDragCompleted2(object sender, Telerik.Windows.DragDrop.DragDropCompletedEventArgs args)
        {
            var data = DragDropPayloadManager.GetDataFromObject(args.Data, "DragData");
            ((IList)(sender as RadGridView).ItemsSource).Remove(data);
        }
    }

    thanks

  2. Answer
    Nick
    Admin
    Nick avatar
    593 posts

    Posted 09 Dec 2014 Link to this post

    Hello Michal,

    You can set the effects for the HeaderRow drop in the DragOver event(handledEventsToo set to true) to be able to drop on it. The reason that prevents you from dropping as it is is that we handle the event internally and disable the drop if the carried data does not meet the requirements for header row drop. 

    Hope this makes sense. 

    Regards,
    Nick
    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.

     
  3. Michal
    Michal avatar
    11 posts
    Member since:
    Jul 2014

    Posted 09 Dec 2014 in reply to Nick Link to this post

    Hi Nick,

    I don't understand what to set in DragOver event handler. Can you write a quick example of a DragOver handler method?

    Thanks.
  4. Nick
    Admin
    Nick avatar
    593 posts

    Posted 09 Dec 2014 Link to this post

    Hi Michal,

    Here are a couple of examples with DragOver implementations:
    http://demos.telerik.com/silverlight/#DragAndDrop/TreeToGrid
    http://demos.telerik.com/silverlight/#GridView/RowReorder

    Hope this helps. 

    Regards,
    Nick
    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.

     
  5. Michal
    Michal avatar
    11 posts
    Member since:
    Jul 2014

    Posted 10 Dec 2014 in reply to Nick Link to this post

    I made it working. I simply added  DragOver handler for each grid cell and now I can drop to a header cell.
    BUT
    When I drop to a header cell, Drop event is fired twice. (for a non-header cell, event is fired once)
    Do you have an idea why?

    code

    private void MyGridOnCellLoaded(object sender, CellEventArgs e)
    {
        Telerik.Windows.DragDrop.DragDropManager.AddDragOverHandler(e.Cell, OnDragOver, true);
    }
     
    private void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
    {
        e.Effects = DragDropEffects.All;
        e.Handled = true;
    }

  6. Nick
    Admin
    Nick avatar
    593 posts

    Posted 10 Dec 2014 Link to this post

    Hello Michal,

    There are a couple of reasons for that. The first is to have more than one Handlers assigned to the event(double subscription). The second is that you are not handling the Drop event(e.Handled = true) and the event is fired for every Drop enabled element.

    Regards,
    Nick
    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.

     
  7. Michal
    Michal avatar
    11 posts
    Member since:
    Jul 2014

    Posted 11 Dec 2014 in reply to Nick Link to this post

    I've figured it out.
    Adding drop handler with true param to whole grid causes executing drop handler twice after dropping to a header cell.
    I removed true param and added a drop handler to each header cell in OnCellLoaded method.
    Now drop handler is executed only once for a standart cell and also for a header cell.

    code

    Telerik.Windows.DragDrop.DragDropManager.AddDropHandler(MyGrid, OnDrop2);
     
    private void MyGridOnCellLoaded(object sender, CellEventArgs e)
    {
        Telerik.Windows.DragDrop.DragDropManager.AddDragOverHandler(e.Cell, OnDragOver, true);
        if (e.Cell is GridViewHeaderCell)
        {
            Telerik.Windows.DragDrop.DragDropManager.AddDropHandler(e.Cell, OnDrop2);
        }
    }
Back to Top