or
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
Hi
RadGridView has property AllowColumnReorder.
How can I disable reordering specific column?
In my case I don`t want let user move first column, all other columns can be reordered.
Regards
