New to Telerik UI for WinForms? Download free 30-day trial

How to DragDrop from RadTreeView to RadSyntaxEditor in DocumentWindow

Environment

Product Version Product Author
2022.2.622 RadSyntaxEditor for WinForms Dinko Krastev

Description

In this example, we will demonstrate how to drag drop RadTreeView nodes and show files in RadSyntaxEditor on drop operation. In this case, both controls are placed inside RadDock.

treeview-dragdrop-dock-syntaxeditor001

Solution

  1. To make this work, first, we need to override GetDropTarget() method of the default TreeViewDragDropService of the RadTreeView. Inside the method, we need to find if there is a RadSyntaxEditor control on the drop position.

public class CustomTreeView : RadTreeView
{
    //Replace the default element with the custom one
    protected override RadTreeViewElement CreateTreeViewElement()
    {
        return new CustomTreeViewElement();
    }

    //Enable theming for the control
    public override string ThemeClassName
    {
        get
        {
            return typeof(RadTreeView).FullName;
        }
    }
}

public class CustomTreeViewElement : RadTreeViewElement
{
    //Enable themeing for the element
    protected override Type ThemeEffectiveType
    {
        get
        {
            return typeof(RadTreeViewElement);
        }
    }
    protected override TreeViewDragDropService CreateDragDropService()
    {
        return new CustomDragDropService(this);
    }
}

public class CustomDragDropService : TreeViewDragDropService
{
    public CustomDragDropService(RadTreeViewElement owner) : base(owner) { }
    protected override Telerik.WinControls.ISupportDrop GetDropTarget(Point mousePosition, out Point resultDropLocation)
    {
        ISupportDrop dropTarget = base.GetDropTarget(mousePosition, out resultDropLocation);
        if (dropTarget == null)
        {
            ComponentThemableElementTree elementTree = this.ElementTreeFromPoint(mousePosition);
            if (elementTree != null )
            {
                RadSyntaxEditor syntaxEditor = elementTree.Control as RadSyntaxEditor;
                if (syntaxEditor != null)
                {
                    return syntaxEditor.SyntaxEditorElement;
                }
            }
        }
        return dropTarget;
    }

    private ComponentThemableElementTree ElementTreeFromPoint(Point mousePosition)
    {
        IntPtr hitWindow = NativeMethods.WindowFromPoint(mousePosition.X, mousePosition.Y);

        if (hitWindow == IntPtr.Zero)
        {
            return null;
        }

        Control hitControl = Control.FromHandle(hitWindow);

        while (hitControl != null)
        {
            IComponentTreeHandler treeHandler = hitControl as IComponentTreeHandler;

            if (treeHandler != null)
            {
                return treeHandler.ElementTree;
            }

            hitControl = hitControl.Parent;
        }
        return null;
    }
}

  1. The next step is to create our RadDock control with two windows. In the first one, we can place it inside the RadTreeView control (replaced with the custom one above). We can populate the treeview with nodes pointing to files from the same project. In the second window, we can add RadSyntaxEditor which we are going to use for editing purposes. What's left is to subscribe to the PreviewDragOver and PreviewDragDrop events of the custom DragDropService. In these events, we can allow drop operation only when you are over RadSyntaxEditor and if a drop occurs we can show the document in the control.

public class MyFile
{
    public MyFile(string fullPath, string name)
    {
        this.FullPath = fullPath;
        this.Name = name;
    }

    public string FullPath
    {
        get;
        set;
    }

    public string Name
    {
        get;
        set;
    }
}

public partial class RadForm1 : Telerik.WinControls.UI.RadForm
{
    BindingList<MyFile> myFiles = new BindingList<MyFile>();
    public RadForm1()
    {
        InitializeComponent();
        customTreeView.AllowDragDrop = true;
        customTreeView.MultiSelect = true;
        this.radSyntaxEditor1.AllowDrop = true;
        PopulateRadTreeView();
        this.customTreeView.TreeViewElement.DragDropService.PreviewDragOver += DragDropService_PreviewDragOver;
        this.customTreeView.TreeViewElement.DragDropService.PreviewDragDrop += DragDropService_PreviewDragDrop;
    }

    private void PopulateRadTreeView()
    {
        string[] filePaths = Directory.GetFiles(@"../../").Where(x=>x.EndsWith(".cs")).ToArray();
        foreach (var item in filePaths)
        {
            myFiles.Add(new MyFile(item,item.Remove(0,6)));

        }
        customTreeView.DataSource = myFiles;
        customTreeView.DisplayMember = "Name";
    }

    private void DragDropService_PreviewDragDrop(object sender, RadDropEventArgs e)
    {
        TreeNodeElement draggedNodeElement = e.DragInstance as TreeNodeElement;
        if (draggedNodeElement == null)
        {
            return;
        }
        e.Handled = true;
        var myFile = draggedNodeElement.Data.DataBoundItem as MyFile;
        using (StreamReader reader = new StreamReader(myFile.FullPath))
        {
            this.radSyntaxEditor1.Document = new TextDocument(reader);
        }
    }

    private void DragDropService_PreviewDragOver(object sender, Telerik.WinControls.RadDragOverEventArgs e)
    {
        if (e.HitTarget is RadSyntaxEditorElement )
        {
            e.CanDrop = true;
        }
        else
        {
            e.CanDrop = false;
        }
    }
}