Add a RadTreeView with several hierarchy levels. Initially all nodes are collapsed. When you collapse each child node deeper in the hierarchy, use the following code snippet: public Form1() { InitializeComponent(); radTreeView1.CollapseAll(); radTreeView1.TreeViewElement.AutoScrollOnClick = false; } private void radTreeView1_NodeExpandedChanged(object sender, RadTreeViewEventArgs e) { if (e.Node.Expanded) { e.Node.LastNode.EnsureVisible(); radTreeView1.BringIntoView(e.Node.LastNode); } } The last child node is visible, regarding the height, however, the entire node is not visible, regarding the width. Workaround: use RadTreeView.MouseUp event instead. private void radTreeView1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { TreeNodeExpanderItem expander = radTreeView1.ElementTree.GetElementAtPoint(e.Location) as TreeNodeExpanderItem; if (expander != null && expander.Expanded && expander.NodeElement.Data != null) { radTreeView1.BringIntoView(expander.NodeElement.Data.LastNode); } } }
Font settings for particular node made by Property Builder are washed up if the Property Builder is opened again.
In RadTreeView, if AllowPlusMinusAnimation property is true and LoadOnDemand is true as well, plus/minus symbols disappears.
Set separate indent for every node in RadTreeView. Currently we support setting the same indent for every node thorough TreeIndent property.
The images and SignStyle cannot be modified using Visual Style Builder.
Add e.Action in SelectedNodeChanging similar to the one in the standard TreeView.BeforeSelect event which indicates what caused the event - mouse click, key pressed, or other
To reproduce: - Add a RadTreeView which have parent and child nodes to a form. - Expand nodes until the both scrollbars are simultaneously shown. - You will notice that you cannot scroll to the last item. Workaround: - Subscribe to the following ScrollerUpdated event handler: void Scroller_ScrollerUpdated(object sender, EventArgs e) { radTreeView1.TreeViewElement.InvalidateMeasure(); } - You can subscribe to this event with the following line of code: radTreeView1.TreeViewElement.Scroller.ScrollerUpdated += Scroller_ScrollerUpdated;
To reproduce: Add a RadTreeView to a form and use the following code: private List<EntityA> entities = new List<EntityA>(); public Form1() { InitializeComponent(); radTreeView1.TriStateMode = true; entities = new List<EntityA>(); for (int i = 0; i < 10; i++) { var newEntityI = new EntityA(i.ToString()); for (int j = 0; j < 100; j++) { var newEntityJ = new EntityB(j.ToString()); for (int k = 0; k < 1000; k++) { var newEntityK = new EntityC(k.ToString()); newEntityJ.Entities.Add(newEntityK); } newEntityI.Entities.Add(newEntityJ); } entities.Add(newEntityI); } } private void checkBox1_CheckedChanged(object sender, EventArgs e) { foreach (var node in radTreeView1.Nodes) { node.Checked = checkBox1.Checked; } } private void radTreeView1_NodesNeeded(object sender, NodesNeededEventArgs e) { if (e.Parent == null) { foreach (var entity in entities) { e.Nodes.Add(new RadTreeNode(entity.Name, false) { CheckState = ToggleState.Off, Tag = entity }); } } else if (e.Parent.Tag is EntityA) { var currentEntity = e.Parent.Tag as EntityA; foreach (var entity in currentEntity.Entities) { e.Nodes.Add(new RadTreeNode(entity.Name, false) { CheckState = e.Parent.CheckState, Tag = entity }); } } else if (e.Parent.Tag is EntityB) { var currentEntity = e.Parent.Tag as EntityB; foreach (var entity in currentEntity.Entities) { e.Nodes.Add(new RadTreeNode(entity.Name, false) { CheckState = e.Parent.CheckState, Tag = entity }); } } else if (e.Parent.Tag is EntityC) { } } Put a breakpoint in the last If statement, you will notice that the breakpoint is being hit, while it is not if the TrieStateMode is set to false Workaround: Use the following custom RadTreeNode: public class MyTreeNode : RadTreeNode { private FieldInfo triStateField; public MyTreeNode() : base() { } public MyTreeNode(string text) : base(text) { } public MyTreeNode(string text, RadTreeNode[] children) : base(text, children) { } public MyTreeNode(string text, bool expanded) : base(text, expanded) { } public MyTreeNode(string text, Image image) : base(text, image) { } public MyTreeNode(string text, Image image, bool expanded) : base(text, image, expanded) { } public override ToggleState CheckState { get { return base.CheckState; } set { bool set = false; if (this.TreeViewElement != null && this.TreeViewElement.TriStateMode) { if (this.triStateField == null) { this.triStateField = typeof(RadTreeViewElement).GetField("triStateMode", BindingFlags.Instance | BindingFlags.NonPublic); } triStateField.SetValue(this.TreeViewElement, false); set = true; } base.CheckState = value; if (set) { this.triStateField.SetValue(this.TreeViewElement, true); } } } }
To reproduce: Add a RadTreeView with hierarchical data. Select a node with hierarchy level > 0. Call the Clear method of the Nodes collection. Refill the tree, drag and drop a node, you will see that two nodes will be dropped since the previous node's Selected property is set to true. Workaround: private void DetachAllNodes(RadTreeNode parent) { this.CleanNode(parent); foreach (RadTreeNode node in parent.Nodes) { this.DetachAllNodes(node); } } private void CleanNode(RadTreeNode node) { node.Current = false; node.Selected = false; } foreach (RadTreeNode node in tree.Nodes) { this.DetachAllNodes(node); } tree.Nodes.Clear();
Workaround: Instead of {RadTreeNode}.Nodes.Clear(), use while ({RadTreeNode}.Nodes.Count>0) { {RadTreeNode}.Nodes.RemoveAt(0); }
To reproduce: -add RadTreeView and RadButton: -use the following code: public partial class Form1 : Form { public Form1() { InitializeComponent(); List<Distributor> distributors = new List<Distributor>() { new Distributor(432,"Distributor 1"), new Distributor(454,"Distributor 2"), new Distributor(438,"Distributor 3"), new Distributor(455,"Distributor 4") }; List<Distributor> distributors2 = new List<Distributor>() { new Distributor(486,"Distributor 5"), new Distributor(487,"Distributor 6"), new Distributor(498,"Distributor 7"), new Distributor(475,"Distributor 8") }; List<Product> products = new List<Product>(); products.Add(new Product(567, "Bicycle", 5, distributors)); products.Add(new Product(456, "Car", 5000,distributors2)); products.Add(new Product(789, "Bike", 1500,null)); BindingList<Category> categories = new BindingList<Category>(); categories.Add(new Category("Bikes", products)); categories.Add(new Category("Accessories", null)); categories.Add(new Category("Clothing", null)); radTreeView1.DataSource = categories; if ((radTreeView1.DataSource as BindingList<Category>).Count > 0) { radTreeView1.DisplayMember = "Name\\Description\\Name"; radTreeView1.ChildMember = "Categories\\Products\\Distributors"; } } private void radButton1_Click(object sender, EventArgs e) { BindingList<Category> categories = radTreeView1.DataSource as BindingList<Category>; categories.Clear(); } } public class Distributor { private int _id; private string _name; public Distributor(int id, string name) { this._id = id; this._name = name; } public int Id { get { return this._id; } set { this._id = value; } } public string Name { get { return this._name; } set { this._name = value; } } } public class Product { private int _id; private string _description; private float _price; private List<Distributor> _distributors; public List<Distributor> Distributors { get { return this._distributors; } set { this._distributors = value; } } public int ID { get { return _id; } set { _id = value; } } public string Description { get { return _description; } set { _description = value; } } public float Price { get { return _price; } set { _price = value; } } public Product(int id, string description, float price, List<Distributor> distributors) { _id = id; _description = description; _price = price; _distributors = distributors; } } public class Category { public Category(string name, List<Product> products) { _name = name; _products = products; } private List<Product> _products; private string _name; public string Name { get { return _name; } set { _name = value; } } public List<Product> Products { get { return _products; } set { _products = value; } } } When you click the button, ArgumentOutOfRangeException is thrown. Workaround: instead of clearing the BindingList, remove each list item one by one: while (categories.Count>0) { categories.RemoveAt(0); }
FIX. RadTreeView - when adding row in the underlying source, the nodes in the tree are collapsed, even when using DeferRefresh
Workaround: RadTreeView1.TreeViewElement.TreeNodeProvider.Reset()
To reproduce: Add some nodes to a tree, and then clear them and move them to another tree. The inner nodes expand/collapse does not work correctly: void radButton1_Click(object sender, EventArgs e) { tree1.Nodes.Clear(); tree2.Nodes.AddRange(nodes); } RadTreeView tree1 = new RadTreeView(); RadTreeView tree2 = new RadTreeView(); List<RadTreeNode> nodes = new List<RadTreeNode>(); private void Populate(RadTreeView tree) { RadTreeNode n11 = new RadTreeNode("11"); RadTreeNode n12 = new RadTreeNode("12"); RadTreeNode n13 = new RadTreeNode("13"); RadTreeNode n14 = new RadTreeNode("14"); nodes.Add(n11); nodes.Add(n12); nodes.Add(n13); nodes.Add(n14); RadTreeNode n21 = new RadTreeNode("21"); RadTreeNode n22 = new RadTreeNode("22"); RadTreeNode n23 = new RadTreeNode("23"); RadTreeNode n24 = new RadTreeNode("24"); n11.Nodes.Add(n21); n11.Nodes.Add(n22); n11.Nodes.Add(n23); n11.Nodes.Add(n24); RadTreeNode n31 = new RadTreeNode("31"); RadTreeNode n32 = new RadTreeNode("32"); RadTreeNode n33 = new RadTreeNode("33"); RadTreeNode n34 = new RadTreeNode("34"); n21.Nodes.Add(n31); n21.Nodes.Add(n32); n21.Nodes.Add(n33); n21.Nodes.Add(n34); tree.Nodes.AddRange(nodes); } 1. Run 2. Expand all nodes in tree1 3. Select node 23 4. Press button move right 5. Click at "plus" at node 21. -> expand collapse does not work correctly Workaround - instead of calling the Clear method of the Nodes collection, remove them manually: while (tree1.Nodes.Count > 0) { tree1.Nodes.RemoveAt(0); }
ADD. RadTreeView - add NodeRemoving event
FIX. RadTreeView - the tree should keep its selection, expanded nodes and scroll position when new record is added to its underlying data source
If user move on last node of the tree view and move the mouse downwards then "NodeMouseLeave" event does not get fired and if user move left side of the node then it's working fine.
To reproduce: void radTreeView1_EditorInitialized(object sender, TreeNodeEditorInitializedEventArgs e) { TreeViewTextBoxEditor editor = e.Editor as TreeViewTextBoxEditor; BaseTextBoxEditorElement element = (BaseTextBoxEditorElement)editor.EditorElement; element.TextChanging+=new TextChangingEventHandler(element_TextChanging); } void element_TextChanging(object sender, TextChangingEventArgs e) { e.Cancel = true; }
When I execute TreeView.SelectedNodes.Clear() during runtime, the SelctedNodeChanged event is not fired letting me know that the current selected node was changed to no selection. Should that qualify for a selection change event? Eessentially, the selected node has changed, but to no selection. The SelectedNodeChanging event does not fire as well. What event will let me know that a selection has been removed (changed)?
So is there an event triggered for added nodes when using a datasource? I want to set the checked state based on a property on the databound item. Basically this: I have a treeview set like this in Q1 2012: treeViewProjets.DataSource = ViewModel.Projets; treeViewProjets.DisplayMember = @"Nom\Nom"; treeViewProjets.ValueMember = @"Id\Id"; treeViewProjets.ChildMember = @"Projets\ObjetsProjet"; treeViewProjets.NodeAdded += new RadTreeView.RadTreeViewEventHandler(treeViewProjets_NodeAdded); treeViewProjets.NodeAdding += new RadTreeView.RadTreeViewCancelEventHandler(treeViewProjets_NodeAdding); treeViewProjets.NodeFormatting += new TreeNodeFormattingEventHandler(treeViewProjets_NodeFormatting); I get a root node and many child nodes created, but the events NodeAdded and NodeAdding are never triggered, NodeFormatting triggers fine.