This is a migrated thread and some comments may be shown as answers.

D&D functionality for Radgrid to Textbox control

7 Answers 130 Views
DragAndDrop
This is a migrated thread and some comments may be shown as answers.
sudhesh
Top achievements
Rank 1
sudhesh asked on 11 Sep 2013, 12:37 PM
Hi All,

  i have a requirement to implement d&d functionality for radgridview(only drag) to textBox (only drop) control.so i tried the drag and drop demo application comes with the telerik suite. gridview to listbox is working fine and the problem is don't know how to implement for textbox control and textbox value should be either one of the dragging column of gridview in MVVM pattern.

   
<UserControl x:Class="TelerikDragandDrop.MainWindow"
        xmlns:telerikDragandDrop="clr-namespace:TelerikDragandDrop">
 
    <UserControl.Resources>
        <telerikDragandDrop:MainViewModel x:Key="ViewModel"/>
 
         
        <!--Note: With this style we make the ListBoxItems draggable:-->
        <Style TargetType="ListBoxItem" x:Key="WishlistItemStyle" >
            <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
            <Setter Property="telerik:DragDropManager.TouchDragTrigger" Value="TapAndHold"/>
        </Style>
        <Style TargetType="telerik:GridViewRow" x:Key="OrderItemStyle" >
            <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="True" />
            <Setter Property="telerik:DragDropManager.TouchDragTrigger" Value="TapAndHold"/>
        </Style>
 
        <Style TargetType="{x:Type TextBox}" x:Key="textBoxStyle">
            <Setter Property="telerik:DragDropManager.AllowCapturedDrag" Value="False" />
            <Setter Property="telerik:DragDropManager.TouchDragTrigger" Value="TapAndHold"/>
            <Setter Property="Foreground" Value="#777777" />
        </Style>
         
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
 
        
 
        <!--Order-->
        <Border BorderBrush="#C8C9CC" BorderThickness="2" CornerRadius="6" Margin="46 46 0 46"
                Background="White" Grid.Column="1">
            <DockPanel>
                <Border DockPanel.Dock="Top"
                        Background="{telerik:Windows8Resource ResourceKey=AccentBrush}" CornerRadius="4 4 0 0">
                    <TextBlock Text="Order" Foreground="{telerik:Windows8Resource ResourceKey=MainBrush}" Margin="20 5 5 5" FontSize="14" />
                </Border>
                <!--NOTE: The GridView is a drop target, we set the AllowDrop to true.-->
                <telerik:RadGridView x:Name="orderView" IsReadOnly="True" Grid.Column="1" Grid.Row="0" Margin="0,0,0,5"
                                     RowIndicatorVisibility="Collapsed" GroupRenderMode="Flat" ItemsSource="{Binding AllApplications, Source={StaticResource ViewModel}}"
                                     RowStyle="{StaticResource OrderItemStyle}" CanUserFreezeColumns=" False" CanUserInsertRows="False"
                                     CanUserReorderColumns="False" CanUserSortColumns="False" ShowGroupPanel="False" Padding="5" AllowDrop="True"
                                     telerikDragandDrop:GridViewDragDropBehavior.IsEnabled="True" Height="115">
                    <telerik:RadGridView.Resources>
                         
                        <DataTemplate x:Key="DraggedItemTemplate">
                            <StackPanel>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="Dragging:"/>
                                    <TextBlock Text="{Binding CurrentDraggedItem.FirstName}" FontWeight="Bold"/>
                                </StackPanel>
                                 
                            </StackPanel>
                        </DataTemplate>
                    </telerik:RadGridView.Resources>
                </telerik:RadGridView>
            </DockPanel>
        </Border>
 
        <!--Whishlist-->
        <Border BorderBrush="#C8C9CC" BorderThickness="2" CornerRadius="6" Margin="46"
                Background="White" Grid.Column="2">
            <DockPanel>
                <Border DockPanel.Dock="Top"
                        Background="{telerik:Windows8Resource ResourceKey=AccentBrush}" CornerRadius="4 4 0 0">
                    <TextBlock Text="Wishlist" Margin="20 5 5 5" Foreground="{telerik:Windows8Resource ResourceKey=MainBrush}" FontSize="14" />
                </Border>
                <!--NOTE: The ListBox is a drop target, we set the AllowDrop to true.-->
                <ListBox x:Name="wishlistView" Grid.Column="1" Grid.Row="1"
                         SelectionMode="Extended"
                         ItemsSource="{Binding MyApplications, Source={StaticResource ViewModel}}" FontSize="11"
                      
                         ItemContainerStyle="{StaticResource WishlistItemStyle}" Padding="5" AllowDrop="True"
                         telerikDragandDrop:ListBoxDragDropBehavior.IsEnabled="True"
                         telerik:TouchManager.IsTouchHitTestVisible="True">
                    <ListBox.Resources>
                       
                        <DataTemplate x:Key="DraggedItemTemplate">
                            <StackPanel>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="Dragging:"/>
                                    <TextBlock Text="{Binding CurrentDraggedItem.FirstName}" FontWeight="Bold"/>
                                </StackPanel>
                               
                            </StackPanel>
                             
                        </DataTemplate>
                    </ListBox.Resources>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid Width="150">
                                <Grid.RowDefinitions>
                                    <RowDefinition />
                                    <RowDefinition />
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                               <TextBlock Grid.Row="1" Text="{Binding FirstName}" FontWeight="Bold"
                                   HorizontalAlignment="Center" Foreground="#FF767676"/>
                                <TextBlock Text="{Binding LastName}" Grid.Row="2"
                                   HorizontalAlignment="Center" Foreground="#FF767676"/>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DockPanel>
        </Border>
        <TextBox Height="35" Name="TextBox1" Style="{StaticResource textBoxStyle}"  AllowDrop="True"   Width="225" Grid.Column="2" Margin="24,204,13,8"   telerikDragandDrop:TextBoxDragDropBehaviour.IsEnabled="True"  telerik:TouchManager.IsTouchHitTestVisible="True" />
    </Grid>
</UserControl>
public class TextBoxDragDropBehaviour
   {
       private TextBox _associatedObject;
 
       /// <summary>
       /// AssociatedObject Property
       /// </summary>
       public TextBox AssociatedObject
       {
           get
           {
               return _associatedObject;
           }
           set
           {
               _associatedObject = value;
           }
       }
 
       private static Dictionary<TextBox, TextBoxDragDropBehaviour> instances;
 
       static TextBoxDragDropBehaviour()
       {
           instances = new Dictionary<TextBox, TextBoxDragDropBehaviour>();
       }
 
       public static bool GetIsEnabled(DependencyObject obj)
       {
           return (bool)obj.GetValue(IsEnabledProperty);
       }
 
       public static void SetIsEnabled(DependencyObject obj, bool value)
       {
           TextBoxDragDropBehaviour behavior = GetAttachedBehavior(obj as TextBox );
 
           behavior.AssociatedObject = obj as TextBox;
 
           if (value)
           {
               behavior.Initialize();
           }
           else
           {
               behavior.CleanUp();
           }
           obj.SetValue(IsEnabledProperty, value);
       }
 
       // Using a DependencyProperty as the backing store for IsEnabled.  This enables animation, styling, binding, etc...
       public static readonly DependencyProperty IsEnabledProperty =
           DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(TextBoxDragDropBehaviour),
               new PropertyMetadata(new PropertyChangedCallback(OnIsEnabledPropertyChanged)));
       public static void OnIsEnabledPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
       {
           SetIsEnabled(dependencyObject, (bool)e.NewValue);
       }
 
       private static TextBoxDragDropBehaviour GetAttachedBehavior(TextBox listBox)
       {
           if (!instances.ContainsKey(listBox))
           {
               instances[listBox] = new TextBoxDragDropBehaviour();
               instances[listBox].AssociatedObject = listBox;
           }
 
           return instances[listBox];
       }
 
       protected virtual void Initialize()
       {
           this.UnsubscribeFromDragDropEvents();
           this.SubscribeToDragDropEvents();
       }
 
       protected virtual void CleanUp()
       {
           this.UnsubscribeFromDragDropEvents();
       }
 
       private void SubscribeToDragDropEvents()
       {
           DragDropManager.AddDragInitializeHandler(this.AssociatedObject, OnDragInitialize);
           DragDropManager.AddGiveFeedbackHandler(this.AssociatedObject, OnGiveFeedback);
           DragDropManager.AddDropHandler(this.AssociatedObject, OnDrop);
           DragDropManager.AddDragDropCompletedHandler(this.AssociatedObject, OnDragDropCompleted);
           DragDropManager.AddDragOverHandler(this.AssociatedObject, OnDragOver);
       }
 
       private void UnsubscribeFromDragDropEvents()
       {
           DragDropManager.RemoveDragInitializeHandler(this.AssociatedObject, OnDragInitialize);
           DragDropManager.RemoveGiveFeedbackHandler(this.AssociatedObject, OnGiveFeedback);
           DragDropManager.RemoveDropHandler(this.AssociatedObject, OnDrop);
           DragDropManager.RemoveDragDropCompletedHandler(this.AssociatedObject, OnDragDropCompleted);
           DragDropManager.RemoveDragOverHandler(this.AssociatedObject, OnDragOver);
       }
 
       private void OnDragInitialize(object sender, DragInitializeEventArgs e)
       {
           DropIndicationDetails details = new DropIndicationDetails();
           var listBoxItem = e.OriginalSource as System.Windows.Controls.ListBoxItem ?? (e.OriginalSource as FrameworkElement).ParentOfType<System.Windows.Controls.ListBoxItem>();
 
           var textBox = sender as System.Windows.Controls.TextBox;
           if (textBox != null)
           {
               var item = listBoxItem != null ? listBoxItem.DataContext : textBox.Text;
               details.CurrentDraggedItem = item;
 
               IDragPayload dragPayload = DragDropPayloadManager.GeneratePayload(null);
 
               dragPayload.SetData("DraggedData", item);
               dragPayload.SetData("DropDetails", details);
 
               e.Data = dragPayload;
           }
 
           e.DragVisual = new DragVisual()
           {
               Content = details,
               ContentTemplate = this.AssociatedObject.Resources["DraggedItemTemplate"] as DataTemplate
           };
           e.DragVisualOffset = e.RelativeStartPoint;
           e.AllowedEffects = DragDropEffects.All;
       }
 
       private void OnGiveFeedback(object sender, Telerik.Windows.DragDrop.GiveFeedbackEventArgs e)
       {
           e.SetCursor(Cursors.Arrow);
           e.Handled = true;
       }
 
       private void OnDragDropCompleted(object sender, DragDropCompletedEventArgs e)
       {
           var draggedItem = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData");
 
           if (e.Effects != DragDropEffects.None)
           {
               //var collection = (sender as TextBox).Text;
               //collection.Remove(draggedItem);
           }
       }
 
       private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
       {
           var draggedItem = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData");
           var details = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails") as DropIndicationDetails;
           var itemsType = (this.AssociatedObject.Text);
 
           //if (details == null || draggedItem == null || draggedItem.GetType() != itemsType)
           //{
           //    return;
           //}
 
           if (e.Effects != DragDropEffects.None)
           {
               var collection = (sender as TextBox);
               if (collection != null) collection.Text = collection.Text;
           }
       }
 
       private void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
       {
           //var draggedItem = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData");
           //var itemsType = (this.AssociatedObject.ItemsSource as IList).AsQueryable().ElementType;
 
           //if (draggedItem.GetType() != itemsType)
           //{
           //    e.Effects = DragDropEffects.None;
           //}
 
           //var dropDetails = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails") as DropIndicationDetails;
           //dropDetails.CurrentDraggedOverItem = this.AssociatedObject;
           //dropDetails.CurrentDropPosition = Controls.DropPosition.Inside;
 
           e.Handled = true;
       }
   }

7 Answers, 1 is accepted

Sort by
0
Yoan
Telerik team
answered on 16 Sep 2013, 03:31 PM
Hello sudhesh,

I have prapared a sample project showing you how to drop into the textbox. You can find the demo project attached. Please examine it and let me know if it fits in your scenario.

Regards,
Yoan
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
David
Top achievements
Rank 1
answered on 22 May 2014, 02:31 PM
This example appears to do exactly what I want. I even modified it to have the grid view and textbox in different windows within the same app and it still works. Unfortunately the exact same thing does not work in my app which is way to large to split out and I have been unable to reproduce my error. Just wondered if anyone knew the answer right off or could point me in the right direction, could save me a lot of time (already wasted several hours on this). 

I am trying to drag a row from a grid view to a text box. I am dragging a row (actually the object the row is bound to) from the grid and the text box has to look at the object and determine whether it can be dropped and how to drop it. The problem is that the text box's OnDrop event does not get called unless the drop payload has a Text entry in it. I don't want a Text entry in it because I am not dragging text and I end up being able to drop these objects in all kinds of places that I should not. Also, the default behavior is wrong, how the text should be displayed in the textbox is different based on the drop target. Note that my DragEnter, DragLeave, DragOver events all get called fine. I tried setting handledEvents to true when registering the event handler with the DragDropManager and I tried using Preview events. OnDrop is never called. If I add a Text entry to the payload OnDrop gets called fine.

Your example does not appear to be adding the Text entry to the payload but it works. Can anyone think of something I might be doing differently?

Thanks
Dave Goughnour...







0
Nick
Telerik team
answered on 23 May 2014, 07:11 AM
Hi David,

The TextBox in WPF has an internal Drag and Drop behavior that is very hard to override. In order to be able to drop in it you have to set a "Text" data in your payload/DataObject.

Hope this helps. 

Regards,
Nik
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
David
Top achievements
Rank 1
answered on 23 May 2014, 10:11 AM
Thanks, this is more out of curiosity but the thing that confused me is that the example referenced above does not appear to include Text in the payload and it works. Am I missing something?

I can put Text in the payload in my app I just have to go around to other places and add code to exclude dropping this Text where it does not belong. Kind of ugly but it works.

I am actually thinking a cleaner solution might be to write my own textbox...

Thanks again
Dave Goughnour
0
Nick
Telerik team
answered on 28 May 2014, 07:40 AM
Hi David,

The project that is included in the thread is overriding the TextBox's drag drop functionality in the TextBoxDragDropBehavior class. It basically sets the text of the TextBox to the ToString value if the dragged object. 

Hope this helps. 

Regards,
Nik
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
David
Top achievements
Rank 1
answered on 28 May 2014, 11:19 AM
I did exactly the same thing in my app. I 'borrowed' the TextBoxDragDropBehavior class and used it in my app. The behavior's drop handler was only called if I added a Text entry to my drag payload. But the sample does not seem to be adding a Text entry. In fact the sample's payload looks almost exactly like the one in my app (different classes obviously). But in my app the target's drop handler is not called unless I also add a Text entry. Again, more of a curiosity at this point but I still don't understand what I am doing different.
0
Nick
Telerik team
answered on 30 May 2014, 10:31 AM
Hi David,

The problem is that the TextBox's internal drag drop logic sets the DragEffects to none if there is no Text present, and therefore the logic in the Drop event is not executed. 

Hope this helps. 

Regards,
Nik
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
Tags
DragAndDrop
Asked by
sudhesh
Top achievements
Rank 1
Answers by
Yoan
Telerik team
David
Top achievements
Rank 1
Nick
Telerik team
Share this question
or