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

RadTextBox start DragDrop

6 Answers 227 Views
TextBox
This is a migrated thread and some comments may be shown as answers.
Marco
Top achievements
Rank 2
Veteran
Marco asked on 26 Jun 2014, 03:29 PM
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

6 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 01 Jul 2014, 08:14 AM
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.
 
0
Marco
Top achievements
Rank 2
Veteran
answered on 03 Jul 2014, 02:28 PM

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

0
Accepted
Dimitar
Telerik team
answered on 08 Jul 2014, 10:01 AM
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.
 
0
Marco
Top achievements
Rank 2
Veteran
answered on 09 Jul 2014, 09:50 AM
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 ? 
0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 14 Jul 2014, 07:46 AM
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.
 
0
Marco
Top achievements
Rank 2
Veteran
answered on 25 Jul 2014, 08:40 AM
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.
Tags
TextBox
Asked by
Marco
Top achievements
Rank 2
Veteran
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Marco
Top achievements
Rank 2
Veteran
Dimitar
Telerik team
Share this question
or