RadTextBox start DragDrop

7 posts, 2 answers
  1. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 26 Jun 2014 Link to this post

    Hello Telerik,

    I'm trying to add some DragDrop support to my forms and their RadTextBox (move/copy textbox content to another textbox only. Not a dragdop inside the same textbox).

    I have some problems to start the operations because when an user make some mouse move with the left button pressed, the radtextbox start selecting the text from the pointer position (like Notepad do).

    The perfect case is to have a behavior corresponding to the RadRichTextBox (or Microsoft Word). If you click and move when some text is selected, a dragdrop operation is started. If you click and move without any text selected, a selection operation is started (the current behavior).

    Which event should I handle to make it work ? (RadTextbox mousemove don't trig, RadTextBox.TextBoxElement mouvemove do trigger but I can't get any information about the selected text from it !)

    Thanks for reading

  2. Dess
    Admin
    Dess avatar
    1609 posts

    Posted 01 Jul 2014 Link to this post

    Hello Marco,

    Thank you for writing.

    Here is a sample code snippet, demonstrating how to achieve drag and drop from a RadTextBox to another RadTextBox, when there is selected text in the source RadTextBox:
    public Form1()
    {
        InitializeComponent();
         
        this.radTextBox1.TextBoxElement.AllowDrag = true;
     
        this.radTextBox1.TextBoxElement.MouseUp += TextBoxElement_MouseUp;
        this.radTextBox1.TextBoxElement.MouseDown += TextBoxElement_MouseDown;
     
        this.radTextBox2.TextBoxElement.TextBoxItem.HostedControl.AllowDrop = true;
        this.radTextBox2.TextBoxElement.TextBoxItem.HostedControl.DragEnter += HostedControl_DragEnter;
        this.radTextBox2.TextBoxElement.TextBoxItem.HostedControl.DragDrop += HostedControl_DragDrop;
    }
     
    int selectionStart = 0;
    int selectionLength = 0;
    string selectedText = string.Empty;
     
    private void TextBoxElement_MouseUp(object sender, MouseEventArgs e)
    {
        //keep the selected text
        selectionStart = this.radTextBox1.SelectionStart;
        selectionLength = this.radTextBox1.SelectionLength;
        selectedText = this.radTextBox1.SelectedText;
    }
     
    private void TextBoxElement_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left && selectedText != string.Empty)
        {
            this.radTextBox1.SelectionStart = selectionStart;
            this.radTextBox1.SelectionLength = selectionLength;
            this.radTextBox1.DoDragDrop(this.radTextBox1.SelectedText, DragDropEffects.Move);
        }
    }
     
    private void HostedControl_DragEnter(object sender, DragEventArgs e)
    {
        IDataObject dataObject = e.Data;
        if (dataObject == null)
            e.Effect = DragDropEffects.None;
        else
        {
            string draggedText = dataObject.GetData(typeof(string)).ToString();
            if (draggedText != null && draggedText != string.Empty)
                e.Effect = e.AllowedEffect;
            else
                e.Effect = DragDropEffects.None;
        }
    }
     
    private void HostedControl_DragDrop(object sender, DragEventArgs e)
    {
        this.radTextBox2.Text = (string)e.Data.GetData(DataFormats.Text);
        selectedText = string.Empty;
    }

    I hope this information helps. Should you have further questions, I would be glad to help.
     
    Regards,
    Desislava
    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.
     
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 03 Jul 2014 in reply to Dess Link to this post

    Hi Desislava,

    Thank you for your answer and your code sample.

    I tested your solution over a sample projet with two RadTextBox. It's working fine except a little bug. 

    Select the text, then begin a dragdrop to an illegal destination (releasing the mouse not in the destination textbox).

    After that when you click back on the first textbox, the selection is stuck. (certainly because the selectedText is not reset as you don't go in HostedConrol_DragDrop in this scenario). 


    As I have at least 32 RadTextBoxes on my form, I have tried to adapt your code for something more generic. Because I'm not really a big fan of writing 4 x 32 Sub for this.

    The WireEvent_And_Configure_DragDropableRadTextBox() and the list are called on the constructor of the form.

    My generic solution is a little buggy.

    * The drag and drop do not start sometime (Text is selected instead of beginning DragDrop)
    * Some Time the data are drop'ed' when I make a simple click on a Textbox. 

    Exemple:
    I have a textbox with "Honolulu". I select the whole text with the mouse. I try to begin dragdrop but it's select half of the word instead ("Hono"). I click again to make a whole selection with the most and the text "Hono" is dropped on the textbox.

    I think that's there is something to improve with the selectedText !

    Private DragDropableRadTextBoxs As List(Of RadTextBox)
     
        Private Sub WireEvent_And_Configure_DragDropableRadTextBox()
            For Each aRadTextBox As RadTextBox In DragDropableRadTextBoxs
                aRadTextBox.TextBoxElement.AllowDrag = True
                aRadTextBox.TextBoxElement.TextBoxItem.HostedControl.AllowDrop = True
                AddHandler aRadTextBox.TextBoxElement.MouseUp, AddressOf DragDropableRadTextBox_MouseUp
                AddHandler aRadTextBox.TextBoxElement.MouseDown, AddressOf DragDropableRadTextBox_MouseDown
                AddHandler aRadTextBox.TextBoxElement.TextBoxItem.HostedControl.DragEnter, AddressOf DragDropableRadTextBox_DragEnter
                AddHandler aRadTextBox.TextBoxElement.TextBoxItem.HostedControl.DragDrop, AddressOf DragDropableRadTextBox_DragDrop
            Next
        End Sub
     
        Private selectionStart As Integer = 0
        Private selectionLength As Integer = 0
        Private selectedText As String = String.Empty
     
        Private Sub DragDropableRadTextBox_MouseUp(sender As System.Object, e As System.Windows.Forms.MouseEventArgs)
            Dim TextBox As RadTextBox = CType(sender, RadTextBoxElement).TextBoxItem.HostedControl.Parent
     
            selectionStart = TextBox.SelectionStart
            selectionLength = TextBox.SelectionLength
            selectedText = TextBox.SelectedText
        End Sub
     
        Private Sub DragDropableRadTextBox_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs)
     
            If e.Button = Windows.Forms.MouseButtons.Left AndAlso selectedText <> String.Empty Then
                Dim TextBox As RadTextBox = CType(sender, RadTextBoxElement).TextBoxItem.HostedControl.Parent
     
                TextBox.SelectionStart = selectionStart
                TextBox.SelectionLength = selectionLength
                DoDragDrop(TextBox.SelectedText, DragDropEffects.Copy Or DragDropEffects.Move)
            End If
        End Sub
     
        Private Sub DragDropableRadTextBox_DragEnter(sender As System.Object, e As System.Windows.Forms.DragEventArgs)
            Dim dataObject As IDataObject = e.Data
     
            If dataObject Is Nothing Then
                e.Effect = DragDropEffects.None
            Else
                Dim draggedText As String = dataObject.GetData(GetType(String)).ToString()
     
                If draggedText IsNot Nothing AndAlso draggedText <> String.Empty Then
                    e.Effect = e.AllowedEffect
                Else
                    e.Effect = DragDropEffects.None
                End If
            End If
        End Sub
     
        Private Sub DragDropableRadTextBox_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs)
            Dim TextBox As RadTextBox = TryCast(sender.Parent, RadTextBox)
     
            TextBox.Text &= CStr(e.Data.GetData(DataFormats.Text))
            selectedText = String.Empty
     
        End Sub

  5. Answer
    Dimitar
    Admin
    Dimitar avatar
    1415 posts

    Posted 08 Jul 2014 Link to this post

    Hello Marco,

    Thank you for writing back.

    First to disable the text copying for the same text box you can check if the text is dropped in different text box within the DragDrop event:
    Private current As RadTextBox
     
    Private Sub DragDropableRadTextBox_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs)
        Dim TextBox As RadTextBox = TryCast(DirectCast(sender, RadTextBoxElement).TextBoxItem.HostedControl.Parent, RadTextBox)
        initialMousePos = e.Location
        If e.Button = System.Windows.Forms.MouseButtons.Left AndAlso selectionLength > 0 Then
            current = TextBox
            TextBox.SelectionStart = selectionStart
            TextBox.SelectionLength = selectionLength
        End If
    End Sub
     
    Private Sub DragDropableRadTextBox_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs)
        Dim TextBox As RadTextBox = TryCast(DirectCast(sender, HostedTextBoxBase).Parent, RadTextBox)
        If current <> TextBox Then
            TextBox.Text += Convert.ToString(e.Data.GetData(DataFormats.Text))
            selectedText = String.Empty
        End If
    End Sub

    Please note that in this case the default dotNet Ole drag and drop functionality is used and it appears that it has some limitations. For example if you select  text and release the mouse outside of the textbox, the text would not be stored (on MouseUp) and the drag and drop cannot be started. So in order this solution to work you should always release the mouse within the textbox when selecting. We cannot implement this in a different way since we do not know at which point the user wants to select text or wants to start a drag and drop operation.

    Do not hesitate to contact us if you have other questions.

    Regards,
    Dimitar
    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.
     
  6. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 09 Jul 2014 in reply to Dimitar Link to this post

    Hi Dimitar,
    Thanks you for your explanation for the mouse release out of the control (which do not start the MouseUp event).
    One solution would be to store the textbox on the MouseDown event and find a "Global" MouseUpEvent on Windows. So we can get back the textbox and then check the selected text lenght. But another global MouseDown event should be able to clear the textbox reference when the user click anywhere.

    But a simple reference to my user about releasing the mouse over the control

    Thanks for you support.

    Could you just change "If current <> TextBox Then" by "If current IsNot TextBox Then" and remove "initialMousePos = e.Location" from your code sample ? 
  7. Answer
    Dess
    Admin
    Dess avatar
    1609 posts

    Posted 14 Jul 2014 Link to this post

    Hello Marco,

    Thank you for writing back.

    It is possible to detect mouse move/release at a global level using mouse hook. Please find attached the modified sample project, demonstrating how to stop the drag and drop operation when the mouse is released no matter over which control.

    Please refer to the following useful links, related to capturing mouse events: I hope this information helps. If you have any additional questions, please let me know.

    Regards,
    Desislava
    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.
     
  8. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 25 Jul 2014 in reply to Dess Link to this post

    Hi Desislava,

    Big up for your sample and the mouse detector class.

    It's has solved the last know bug for our DragDropableRadTextBox.

    The links were also very interesting.
Back to Top
UI for WinForms is Visual Studio 2017 Ready