Hello,
I have an application were I include a Treeview.
I have some issues with my screen,
when I manipulate this treeview with drag and drop functionality.
The treeview get's rendered and is only showing a part.
It's like the scrollbar is not on the correct position.
When I scroll with the mouse up and down it will be rendered correct again.
This issue appear's when I reorder the treeview with the mouse, aswell in code.
It's not predictable when it occurs.
Has anyone an idea how to fix this ?
using System;using System.Collections.Generic;using System.Diagnostics;using System.Drawing;using System.Drawing.Drawing2D;using System.Linq;using System.Windows.Forms;using Telerik.WinControls;using Telerik.WinControls.Data;using Telerik.WinControls.UI;namespace SortAccountsSpike{    public partial class SortAccountsForm : Form    {        private Object _currentTargetDataBoundItem;          public SortAccountsForm()        {            InitializeComponent();          //  _dataList = new ObservableCollection<AccountGroup>();        }        protected override void OnLoad(EventArgs e)        {            base.OnLoad(e);            AutoScroll = false;            radTreeView1.TreeViewElement.NodeFormatting += TreeViewElement_NodeFormatting;            radTreeView1.DragStarting += RadTreeView1DragStarting;            radTreeView1.DragOverNode += RadTreeView1DragOverNode;            radTreeView1.DragEnding += RadTreeView1DragEnding;            radTreeView1.TreeViewElement.AutoSizeItems = true;            radTreeView1.ShowLines = true;            radTreeView1.ShowRootLines = true;            radTreeView1.ShowExpandCollapse = true;            radTreeView1.FullRowSelect = true;            radTreeView1.LineStyle = TreeLineStyle.Dot;            radTreeView1.MultiSelect = true;            radTreeView1.ShowNodeToolTips = true;            radTreeView1.TreeViewElement.Comparer = new AccounNodeComparer(radTreeView1.TreeViewElement);            radTreeView1.NodeExpandedChanging += radTreeView1_NodeExpandedChanging;            FillTreeView();        }        private void FillTreeView()        {            radTreeView1.ChildMember = @"AccountGroup\Accounts";          //  radTreeView1.DisplayMember = @"GroupName\AccountNumber";            radTreeView1.SortOrder = SortOrder.Ascending;            radTreeView1.DataSource = AccountModel.AccountGroups;        }        void TreeViewElement_NodeFormatting(object sender, TreeNodeFormattingEventArgs e)        {            var treeNodeContentElement = e.NodeElement.ContentElement;            //General styling            /////////////              //  treeNodeContentElement.StretchHorizontally = true;            treeNodeContentElement.Padding = new Padding(5);            treeNodeContentElement.Margin = new Padding(0, 2, 0, 2);            treeNodeContentElement.SmoothingMode = SmoothingMode.AntiAlias;            treeNodeContentElement.DrawBorder = true;            treeNodeContentElement.BorderColor = Color.FromArgb(110, 153, 210);            treeNodeContentElement.DrawFill = true;            treeNodeContentElement.GradientStyle = GradientStyles.Linear;            treeNodeContentElement.NumberOfColors = 2;            //AccountGroupFormatting            var accountGroup = e.Node.DataBoundItem as AccountGroup;            if (accountGroup != null)            {                treeNodeContentElement.Text = accountGroup.ToDisplayHtml();                e.Node.Expanded = accountGroup.Expanded;                //fill                treeNodeContentElement.BackColor = Color.FromArgb(248, 248, 248);                treeNodeContentElement.BackColor2 = Color.FromArgb(233, 233, 233);            }            //Account formatting            var accountInfo = e.Node.DataBoundItem as AccountInfo;              if (accountInfo != null)            {                treeNodeContentElement.Text = accountInfo.ToDisplayHtml();                if (accountInfo.IsVisible)                {                    e.Node.ToolTipText = string.Empty;                    treeNodeContentElement.BackColor = Color.FromArgb(174, 190, 217);                    treeNodeContentElement.BackColor2 = Color.FromArgb(168, 183, 210);                    treeNodeContentElement.ForeColor = Color.Black;                }                else                {                    e.Node.ToolTipText = "This account is not visible in drop down lists.";                    treeNodeContentElement.BackColor = Color.FromArgb(227, 233, 242);                    treeNodeContentElement.BackColor2 = Color.FromArgb(235, 238, 245);                    treeNodeContentElement.ForeColor = Color.FromArgb(153, 153, 153);                }                              }        }        void radTreeView1_NodeExpandedChanging(object sender, RadTreeViewCancelEventArgs e)        {            var group = e.Node.DataBoundItem as AccountGroup;            if (group != null)            {                group.Expanded = !e.Node.Expanded;            }        }        void RadTreeView1DragStarting(object sender, RadTreeViewDragCancelEventArgs e)        {            //don't allow the first group to be moved            if (e.Node.Level == 0 && e.Node.Index == 0)            {                e.Cancel = true;            }                 _currentTargetDataBoundItem = null;        }        void RadTreeView1DragOverNode(object sender, RadTreeViewDragCancelEventArgs e)        {            //determine if the dragged node can be dropped on the current hovered node            if (e.Node != null)            {                e.Cancel = !CanBeDroppedOnTarget(e.Node.DataBoundItem, e.TargetNode.DataBoundItem);            }            else            {                e.Cancel = true;            }        }        void RadTreeView1DragEnding(object sender, RadTreeViewDragCancelEventArgs e)        {            //recheck if it is correct to drop the dragged node on the target node (this event is fired multiple times when multiple nodes are dragged at once)            if (CanBeDroppedOnTarget(e.Node.DataBoundItem, e.TargetNode.DataBoundItem))            {                if (_currentTargetDataBoundItem == null)                     _currentTargetDataBoundItem = e.TargetNode.DataBoundItem;                //execute drag operation                       MoveNode(e.Node.DataBoundItem);                          }                    e.Cancel = true; //cancel event and make the treeview refresh to reflect the changed observable datasource            radTreeView1.Nodes.Refresh();            radTreeView1.SelectedNodes.Clear();        }        private bool CanBeDroppedOnTarget(Object draggedDataBoundItem, Object targetDataBoundItem)        {            var draggedGroup = draggedDataBoundItem as AccountGroup;            var targetGroup = targetDataBoundItem as AccountGroup;            if (draggedGroup != null)            {                //dragged node is a group -> target must also be a group                return (targetGroup != null);            }            else            {                //dragged node is an account                 var draggedAccount = (AccountInfo)draggedDataBoundItem;                //-> if parent is also being dragged, the node cannot be dropped                var parentGroupIsAlsoDragged = radTreeView1.SelectedNodes.Select(n => n.DataBoundItem)                                                           .OfType<AccountGroup>()                                                           .Any(                                                               group =>                                                               group.Accounts.Any(                                                                   account => account.Id == draggedAccount.Id));                return !parentGroupIsAlsoDragged;            }        }        private void MoveNode(Object draggedDataBoundItem)        {            var draggedGroup = draggedDataBoundItem as AccountGroup;            var targetGroup = _currentTargetDataBoundItem as AccountGroup;            var draggedAccount = draggedDataBoundItem as AccountInfo;            var targetAccount = _currentTargetDataBoundItem as AccountInfo;            if (draggedGroup != null)            {                if (targetGroup == null)                {                    throw new InvalidOperationException(                        "Dropping an account group on a node that does not represent an account group is not possible.");                }                MoveAccountGroup(draggedGroup, targetGroup);            }            else            {                //move account                MoveAccount(draggedAccount, targetAccount, targetGroup);            }        }        private void MoveAccount(AccountInfo draggedAccount, AccountInfo targetAccount, AccountGroup targetGroup)        {            Debug.Assert(draggedAccount != null);            AccountGroup draggedGroup = AccountModel.AccountGroups.First(group => @group.Accounts.Contains(draggedAccount));            if (targetAccount != null)            {                targetGroup = AccountModel.AccountGroups.First(group => @group.Accounts.Contains(targetAccount));            }            Debug.Assert(targetGroup != null);            //move down items            var targetSequence = (targetAccount != null) ? targetAccount.Sequence : 0;            var accountInfosToMove = targetGroup.Accounts.Where(accInfo => accInfo.Sequence > targetSequence);            foreach (var accInfo in accountInfosToMove)            {                accInfo.Sequence += 1;            }            //move item            draggedAccount.Sequence = targetSequence + 1;            if (draggedGroup.Id != targetGroup.Id)            {                draggedGroup.Accounts.Remove(draggedAccount);                targetGroup.Accounts.Add(draggedAccount);                NormalizeAccountSequences(draggedGroup.Accounts);            }            NormalizeAccountSequences(targetGroup.Accounts);            if (_currentTargetDataBoundItem is AccountInfo)            {                _currentTargetDataBoundItem = draggedAccount;            }        }        private void MoveAccountGroup(AccountGroup draggedGroup, AccountGroup targetGroup)        {            //move down items            var groupsToMove = AccountModel.AccountGroups.Where(group => @group.Sequence > targetGroup.Sequence);            foreach (var group in groupsToMove)            {                @group.Sequence += 1;            }            //move group            draggedGroup.Sequence = targetGroup.Sequence + 1;            //normalize            NormalizeGroupSequences(AccountModel.AccountGroups);        }        private void NormalizeAccountSequences(IEnumerable<AccountInfo> accountInfosToNormalize)        {            var index = 0;            foreach (var accInfo in accountInfosToNormalize.OrderBy(account => account.Sequence))            {                accInfo.Sequence = ++index;            }        }        private void NormalizeGroupSequences(IEnumerable<AccountGroup> accountGroupsToNormalize)        {            var index = 0;            foreach (var group in accountGroupsToNormalize.OrderBy(group => group.Sequence))            {                group.Sequence = ++index;            }        }        private void MakeVisibleButtonClick(object sender, EventArgs e)        {            ChangVisibilityOfSelectedNodes(true);        }        private void MakeInvisibleButtonClick(object sender, EventArgs e)        {            ChangVisibilityOfSelectedNodes(false);        }        private void ChangVisibilityOfSelectedNodes(bool isvisible)        {            var accountsToChange = radTreeView1.SelectedNodes.Select(n => n.DataBoundItem).OfType<AccountInfo>().ToList();            foreach (var account in accountsToChange)            {                account.IsVisible = isvisible;            }            radTreeView1.Nodes.Refresh();        }        private void ChangeAliasButtonClick(object sender, EventArgs e)        {            string filledInAlias = string.Empty;            var uniquePreferedNames =                (from account in radTreeView1.SelectedNodes.Select(n => n.DataBoundItem).OfType<AccountInfo>()                 group account by account.PreferedName                 into accountGroup                 select accountGroup.Key).ToList();            if (uniquePreferedNames.Count == 1)            {                filledInAlias = uniquePreferedNames.First();            }            var result = InputDialog.ShowInputBox("Edit alias", "Please fill in an alias for the selected account(s)", out filledInAlias, this, filledInAlias);            if (result == DialogResult.OK)            {                var accountsToChange = radTreeView1.SelectedNodes.Select(n => n.DataBoundItem).OfType<AccountInfo>().ToList();                foreach (var account in accountsToChange)                {                    account.PreferedName = filledInAlias;                }                radTreeView1.Nodes.Refresh();            }              }        private static class AccountModel        {            private static ObservableCollection<AccountGroup> _accountGroups;            public static ObservableCollection<AccountGroup> AccountGroups            {                get { return _accountGroups ?? (_accountGroups = LoadInitialDataList()); }            }            private static ObservableCollection<AccountGroup> LoadInitialDataList()            {                var dataCollection = new ObservableCollection<AccountGroup>();                var groupNone = new AccountGroup                    {                    Id = Guid.NewGuid(),                    GroupName = "No group",                    Sequence = 1,                    Expanded = true                };                dataCollection.Add(groupNone);                var groupTest = new AccountGroup                {                    Id = Guid.NewGuid(),                    GroupName = "Some other group",                    Sequence = 2                };                dataCollection.Add(groupTest);                var anotherGroup = new AccountGroup                {                    Id = Guid.NewGuid(),                    GroupName = "Yet another group",                    Sequence = 3                };                dataCollection.Add(anotherGroup);                var item1 = new AccountInfo                {                    Id = Guid.NewGuid(),                    AccountNumber = "1",                    Balance = 154000,                    Currency = "EUR",                    Product = "Alba VZW, Mullens Kris",                    Sequence = 1,                    IsVisible = true                };                groupNone.Accounts.Add(item1);                var item2 = new AccountInfo                {                    Id = Guid.NewGuid(),                    AccountNumber = "2",                    Balance = 500,                    Currency = "EUR",                    Product = "John Doe",                    PreferedName = "The unknown account",                    Sequence = 3,                    IsVisible = true                };                groupNone.Accounts.Add(item2);                var item3 = new AccountInfo                {                    Id = Guid.NewGuid(),                    AccountNumber = "3",                    Balance = -600,                    Currency = "EUR",                    Product = "Jane Doe",                    Sequence = 4                };                groupTest.Accounts.Add(item3);                var item4 = new AccountInfo                {                    Id = Guid.NewGuid(),                    AccountNumber = "4",                    Balance = -600,                    Currency = "EUR",                    Product = "John Denver",                    Sequence = 5                };                groupTest.Accounts.Add(item4);                var item5 = new AccountInfo                {                    Id = Guid.NewGuid(),                    AccountNumber = "5",                    Balance = 600897,                    Currency = "EUR",                    Product = "Richie Vallens",                    Sequence = 6,                    IsVisible = true                };                groupTest.Accounts.Add(item5);                for (int i = 0; i < 10; i++)                {                    var item6 = new AccountInfo                    {                        Id = Guid.NewGuid(),                        AccountNumber = "BE11 2222 3333 4444",                        Balance = -150,                        Currency = "EUR",                        Product = "Donna Summer",                        Sequence = i + 1                    };                    anotherGroup.Accounts.Add(item6);                }                                return dataCollection;            }        }    }    public class AccounNodeComparer : TreeNodeComparer    {        public AccounNodeComparer(RadTreeViewElement treeViewElement)            : base(treeViewElement)        {        }        public override int Compare(RadTreeNode x, RadTreeNode y)        {            //compare 2 account groups            var accountGroup1 = x.DataBoundItem as AccountGroup;            var accountGroup2 = y.DataBoundItem as AccountGroup;            if (accountGroup1 != null && accountGroup2 != null)            {                return accountGroup1.CompareTo(accountGroup2);            }            //compare 2 accounts            var accountInfo1 = x.DataBoundItem as AccountInfo;            var accountInfo2 = y.DataBoundItem as AccountInfo;            if (accountInfo1 != null && accountInfo2 != null)            {                return accountInfo1.CompareTo(accountInfo2);            }            return 0;        }    }}
Kind regards.
Ralf
