Hi there
I found this issue in RadTreeView filtering
I have a 2-level text structure programmatically created
after creation I use the command
radtree.ExpandAll()
This is the only event handled
Private Sub txtFilter_TextChanged(sender As Object, e As EventArgs) Handles txtFilter.TextChanged
radtreeNavigazione.Filter = txtFilter.Text
End Sub
When I set a filter with at least 4 letters and then I select the text in the filter box and press "back", the app freezes with cpu working at 50 %.
I use this workaround to solve
Private Sub txtFilter_TextChanged(sender As Object, e As EventArgs) Handles txtFilter.TextChanged
radtreeNavigazione.Filter = txtFilter.Text
End Sub
I use this workaround
Private Sub txtFilter_TextChanged(sender As Object, e As EventArgs) Handles txtFilter.TextChanged
radtree.CollapseAll()
radtreeNavigazione.Filter = txtFilter.Text
radtree.ExpandAll()
End Sub
In this way it works, but I wanted to report the issue.
Thank you in advance for your attention
Afternoon
We have a RadTReeView that we drag nodes around to reorder within the same treeview.
There are about 2000 nodes in the tree that is a self referencing data bound and goes about 15 levels deep at some parts of the tree
When we click left mouse down (keeping it down) to drag and drop reorder a node, using the mouse wheel to scroll the tree up or down does not work anymore
We want to for instance drag a node from a location to another location outside the current view, using the mouse wheel to navigate the tree view up and down. This used to work, but not after upgrading to the new 2019 telerik.
Is there a tree view control option that needs to be toggled for this to work?
Thank you
Theo
Hi there, through out our app we use the treeview everywhere - but we have had this issue where it crashes when someone right clicks on the treeview where there is no node. This crash happens on the "ContextMenuOpening" event when we try to use e.TreeElement. This is because, on the telerik side of things, the getter for that property is throwing a NullReferenceException (see attached screenshot)
I think this is happening because in your RadTreeViewCancelEventArgs.cs it is this:
public RadTreeViewElement TreeElement
{
get { return node.TreeViewElement; }
}
public RadTreeView TreeView
{
get { return node.TreeView; }
}
But since node == null, it throws the exception. It probably should check for null, and if node is null, return a null for those properties - so we can use null conditional operator to check stuff. We have a workaround but it is just lots of copy and paste of things.
To reproduce: Run the attached application. Drag Node 2 to after Node 4 while holding down the Alt key. Note that the Node 2 copy is inserted before Node 4. When Node 2 is dragged to after Node 4 without holding down the Alt key, Node 2 is correctly moved to after Node 4. Workaround: you can modify the TreeViewDragDropService and control at what position exactly to be inserted the dragged node: https://docs.telerik.com/devtools/winforms/treeview/drag-and-drop/modify-the-dragdropservice-behavior https://docs.telerik.com/devtools/winforms/treeview/drag-and-drop/drag-and-drop-in-bound-mode
To reproduce: use the following code snippet. You will notice that mnemonics are displayed. public RadForm1() { InitializeComponent(); new RadControlSpyForm().Show(); this.radTreeView1.DisplayMember = "name"; this.radTreeView1.ParentMember = "pid"; this.radTreeView1.ChildMember = "id"; this.radTreeView1.DataSource = this.GetSampleData(); this.radTreeView1.NodeFormatting += radTreeView1_NodeFormatting; this.radTreeView1.SelectedNodeChanged += radTreeView1_SelectedNodeChanged; this.radBreadCrumb1.DefaultTreeView = this.radTreeView1; } private void radTreeView1_SelectedNodeChanged(object sender, Telerik.WinControls.UI.RadTreeViewEventArgs e) { foreach (RadSplitButtonElement item in this.radBreadCrumb1.BreadCrumbElement.Items) { item.ActionButton.TextElement.UseMnemonic = false; } } private void radTreeView1_NodeFormatting(object sender, Telerik.WinControls.UI.TreeNodeFormattingEventArgs e) { e.NodeElement.ContentElement.UseMnemonic = false; } private DataTable GetSampleData() { DataTable dt = new DataTable(); DataColumn dc = new DataColumn(); dc.ColumnName = "id"; dc.DataType = typeof(int); dt.Columns.Add(dc); DataColumn dc1 = new DataColumn(); dc1.ColumnName = "name"; dc1.DataType = typeof(string); dt.Columns.Add(dc1); DataColumn dc2 = new DataColumn(); dc2.ColumnName = "pid"; dc2.DataType = typeof(int); dt.Columns.Add(dc2); DataRow dr = dt.NewRow(); dr[0] = 0; dr[1] = "Hello & Goodbye"; dr[2] = DBNull.Value; dt.Rows.Add(dr); dr = dt.NewRow(); dr[0] = 1; dr[1] = @"&C:\"; dr[2] = 0; dt.Rows.Add(dr); dr = dt.NewRow(); dr[0] = 2; dr[1] = @"&D:\"; dr[2] = 0; dt.Rows.Add(dr); dr = dt.NewRow(); dr[0] = 3; dr[1] = "&Program Files"; dr[2] = 1; dt.Rows.Add(dr); dr = dt.NewRow(); dr[0] = 4; dr[1] = "M&icrosoft"; dr[2] = 3; dt.Rows.Add(dr); dr = dt.NewRow(); dr[0] = 5; dr[1] = "&Telerik"; dr[2] = 3; dt.Rows.Add(dr); dr = dt.NewRow(); dr[0] = 6; dr[1] = "&WINDOWS"; dr[2] = 1; dt.Rows.Add(dr); return dt; } Workaround: set the DefaultTreeView before subscribing to the treeview events. this.radBreadCrumb1.DefaultTreeView = this.radTreeView1; this.radTreeView1.NodeFormatting += radTreeView1_NodeFormatting; this.radTreeView1.SelectedNodeChanged += radTreeView1_SelectedNodeChanged;
To reproduce: public RadForm1() { InitializeComponent(); BindingList<Item> items = new BindingList<Item>(); items.Add(new Item(0,"Root", CheckState.Checked,-1)); for (int i = 1; i < 5; i++) { items.Add(new Item(i, "Node" + i, CheckState.Checked,0)); } this.radTreeView1.CheckBoxes = true; this.radTreeView1.DisplayMember = "Name"; this.radTreeView1.ChildMember = "Id"; this.radTreeView1.ParentMember = "ParentId"; this.radTreeView1.CheckedMember = "IsActive"; this.radTreeView1.AutoCheckChildNodes = true; this.radTreeView1.TriStateMode = true; this.radTreeView1.DataSource = items; this.radTreeView1.ExpandAll(); } public class Item { public int Id { get; set; } public string Name { get; set; } public CheckState IsActive { get; set; } public int ParentId { get; set; } public Item(int id, string name, CheckState isActive, int parentId) { this.Id = id; this.Name = name; this.IsActive = isActive; this.ParentId = parentId; } } Workaround: implement a TypeConverter that can handle converting from/to System.Windows.Forms.CheckState. A sample implementation for creating a custom TypeConverter is demonstrated in the following help article: https://docs.telerik.com/devtools/winforms/treeview/data-binding/togglestateconverter
To reproduce: please run the attached sample project and follow the steps in the attached sample gif file. Workaround: instead of filtering the nodes, you can manipulate the RadTreeNode.Visible property considering the filter criteria and whether the node contains a child that matches the filter. public RadForm1() { InitializeComponent(); this.radTreeView1.ShowLines = true; } private void FilterNode(RadTreeNode node) { bool atLeastOneChildMatches = false; ChildNodeContains(this.radTextBox1.Text.ToLower(), node.Nodes, ref atLeastOneChildMatches); if (node.Text.ToLower().Contains(this.radTextBox1.Text.ToLower()) || atLeastOneChildMatches) { node.Visible = true; } else { node.Visible = false; } } private void ChildNodeContains(string filterCritria, RadTreeNodeCollection nodes, ref bool atLeastOneChildMatches) { foreach (RadTreeNode node in nodes) { if (node.Text.ToLower().Contains(filterCritria)) { atLeastOneChildMatches = true; return; } if (atLeastOneChildMatches == false && node.Nodes.Count > 0) { ChildNodeContains(filterCritria, node.Nodes, ref atLeastOneChildMatches); } } } private void radTextBox1_TextChanged(object sender, EventArgs e) { PerformFilter(this.radTreeView1.Nodes); } private void PerformFilter(RadTreeNodeCollection nodes) { foreach (RadTreeNode node in nodes) { FilterNode(node); if (node.Nodes.Count > 0) { PerformFilter(node.Nodes); } } }
To reproduce. - Add 100 nodes so the scroll appears. - Try scrolling to bottom. Workaround: radTreeView1.TreeViewElement.Scroller.ScrollMode = ItemScrollerScrollModes.Discrete;
Scenario: Populate RadTreeView with data coming from an XML: https://docs.telerik.com/devtools/winforms/treeview/data-binding/binding-to-xml-data The XML file stores a boolean value "IsActive" which will determine the check state of the node. Then, specify the RadTreeView. CheckMember property as well string fileName = @"TempFile.xml"; DataSet tocDataSet = new DataSet("Toc"); tocDataSet.ReadXml(fileName); this.radTreeView1.DataMember = "FlatNode"; this.radTreeView1.DisplayMember = "Title"; this.radTreeView1.ChildMember = "Id"; this.radTreeView1.ParentMember = "ParentId"; this.radTreeView1.CheckedMember = "IsActive"; this.radTreeView1.DataSource = tocDataSet; When you try to check/uncheck a node, an exception occurs indicating the inability to convert the string value "On" to ToggleState. Currently RadTreeView supports only bool, bool? to ToggleState and vice versa. The TypeConverter should be exposed so the developer can change it and implement the custom conversion. <?xml version="1.0" encoding="utf-8"?> <ArrayOfFlatNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <FlatNode> <Title>New Name</Title> <IsActive>false</IsActive> <ParentId>0</ParentId> <Id>1</Id> </FlatNode> <FlatNode> <Title>1st Node</Title> <IsActive>false</IsActive> <ParentId>1</ParentId> <Id>2</Id> </FlatNode> <FlatNode> <Title>1.1</Title> <IsActive>true</IsActive> <ParentId>2</ParentId> <Id>3</Id> </FlatNode> <FlatNode> <Title>1.2</Title> <IsActive>false</IsActive> <ParentId>2</ParentId> <Id>4</Id> </FlatNode> <FlatNode> <Title>1.3</Title> <IsActive>false</IsActive> <ParentId>2</ParentId> <Id>5</Id> </FlatNode> <FlatNode> <Title>2.0</Title> <IsActive>true</IsActive> <ParentId>1</ParentId> <Id>6</Id> </FlatNode> <FlatNode> <Title>2.1</Title> <IsActive>true</IsActive> <ParentId>6</ParentId> <Id>7</Id> </FlatNode> <FlatNode> <Title>2.2</Title> <IsActive>true</IsActive> <ParentId>6</ParentId> <Id>8</Id> </FlatNode> <FlatNode> <Title>2.3</Title> <IsActive>true</IsActive> <ParentId>6</ParentId> <Id>9</Id> </FlatNode> <FlatNode> <Title>3.0</Title> <IsActive>true</IsActive> <ParentId>1</ParentId> <Id>10</Id> </FlatNode> <FlatNode> <Title>4.0</Title> <IsActive>false</IsActive> <ParentId>1</ParentId> <Id>11</Id> </FlatNode> <FlatNode> <Title>5.0</Title> <IsActive>true</IsActive> <ParentId>1</ParentId> <Id>12</Id> </FlatNode> <FlatNode> <Title>3.1</Title> <IsActive>false</IsActive> <ParentId>10</ParentId> <Id>13</Id> </FlatNode> <FlatNode> <Title>New Item</Title> <IsActive>true</IsActive> <ParentId>8</ParentId> <Id>15</Id> </FlatNode> <FlatNode> <Title>New Item</Title> <IsActive>true</IsActive> <ParentId>8</ParentId> <Id>16</Id> </FlatNode> </ArrayOfFlatNode>
To reproduce: please refer to the attached project. Workaround: if you access the RadTreeNode.TreeViewElement property, the TreeView property is loaded.
To reproduce: add several nodes at design time in order to obtain a vertical scrollbar. Enable the drag and drop functionality by setting the AllowDragDrop property to true. If you start dragging you will notice that the RadTreeView doesn't auto-scroll when you drag close to the borders of the visible area. Workaround: Class CustomDragDropService Inherits TreeViewDragDropService Public Sub New(ByVal owner As RadTreeViewElement) MyBase.New(owner) End Sub Protected Overrides Sub SetHintWindowPosition(ByVal mousePt As Point) End Sub End Class Class CustomTreeViewElement Inherits RadTreeViewElement Protected Overrides ReadOnly Property ThemeEffectiveType As Type Get Return GetType(RadTreeViewElement) End Get End Property Protected Overrides Function CreateDragDropService() As TreeViewDragDropService Return New CustomDragDropService(Me) End Function End Class Class CustomTreeView Inherits RadTreeView Protected Overrides Function CreateTreeViewElement() As RadTreeViewElement Return New CustomTreeViewElement() End Function Public Overrides Property ThemeClassName As String Get Return GetType(RadTreeView).FullName End Get Set(value As String) MyBase.ThemeClassName = value End Set End Property End Class
Workaround: call the ExpandAll method of the tree removing any nodes
When you start dragging a node you will notice that the drag hint is constantly flickering.
For the MS TreeView the HideSelection property gets or sets a value indicating whether the selected tree node remains highlighted even when the tree view has lost the focus. However, it doesn't work in RadTreeView.
Please refer to the attached sample project. Run the application on a WIndows 10 machine. Switch on the Narrator and try to expand a node then the EnableRadAccessibilityObjects property is set to true. Workaround: set the EnableRadAccessibilityObjects property to false.
How to reproduce: check the attached project Workaround: create a custom TreeViewDragDropService class CustomTreeViewElement : RadTreeViewElement { protected override Type ThemeEffectiveType { get { return typeof(RadTreeViewElement); } } protected override TreeViewDragDropService CreateDragDropService() { return new CustomDragDropService(this); } } class CustomTreeView : RadTreeView { protected override RadTreeViewElement CreateTreeViewElement() { return new CustomTreeViewElement(); } public override string ThemeClassName { get { return typeof(RadTreeView).FullName; } } } class CustomDragDropService : TreeViewDragDropService { public CustomDragDropService(RadTreeViewElement owner) : base(owner) { } protected override bool CancelPreviewDragDrop(RadDropEventArgs e) { return false; } }
Pressing arrow down or up when renaming item on a list with scrollbar throws null pointer exception. Example solution in attachement. Steps to reproduce with attached solution: Scroll down to last element (A99) Press F2 (rename) and rename to "0" Press arrow up or down on a keyboard (without pressing enter after rename). -> NullReferenceException is thrown.
To reproduce: private void RadTreeView1_NodeCheckedChanging(object sender, Telerik.WinControls.UI.RadTreeViewCancelEventArgs e) { Console.WriteLine(e.Action); } The action is always unknown.
To reproduce: public RadForm1() { InitializeComponent(); for (int i = 0; i < 10; i++) { this.radTreeView1.Nodes.Add("Node1." + i); } this.radTreeView1.AllowDragDrop = true; this.radTreeView1.TreeViewElement.DragDropService.PreviewDragDrop+=DragDropService_PreviewDragDrop; } private void DragDropService_PreviewDragDrop(object sender, RadDropEventArgs e) { e.Handled = true; }
To reproduce: for (int i = 0; i < 10; i++) { this.radTreeView1.Nodes.Add("Node1." + i); } this.radTreeView1.AllowDragDrop = true; this.radTreeView1.TreeViewElement.DragDropService.ShowDragHint = false; Workaround: this.radTreeView1.TreeViewElement.DragDropService.PreviewDragHint += DragDropService_PreviewDragHint; private void DragDropService_PreviewDragHint(object sender, PreviewDragHintEventArgs e) { e.UseDefaultHint = false; }