TreeView selected node problem - c#

i wanted to create a custom treeview so i inherited the treeview class and created 'CustomTreeView' class
there i implemented multiselect concept..
for making the node as selected,
node.BackColor = SystemColors.Highlight;
node.ForeColor = SystemColors.HighlightText;
i used these lines...
but the problem is when i make the control as disabled(ie enabled=false),
the selected node goes invisible..
any other solution to make a node selected??? without this enabled problem?
EDIT: Here is the full function that is called when a node is selected:
private void ToggleNode(TreeNode node, bool bSelectNode)
{
if (bSelectNode)
{
m_SelectedNode = node;
if (!m_SelectedNodes.Contains(node))
m_SelectedNodes.Add(node);
node.BackColor = SystemColors.Highlight;
node.ForeColor = SystemColors.HighlightText;
}
else
{
m_SelectedNodes.Remove(node);
node.BackColor = this.BackColor;
node.ForeColor = this.ForeColor;
}
}

I suspect it's because Highlight and HighlightText are sufficiently close together that you get this effect with the dimming.
Try Red and Blue. Does it still disappear?

Related

Make TreeNode not selectable but still functional

I initialize the component in the designer code:
private void InitializeComponent(){
this.treeViewCategory.Name = "treeViewCategory";
this.treeViewCategory.Size = new System.Drawing.Size(287, 303);
this.treeViewCategory.TabIndex = 14;
this.treeViewCategory.DoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeViewCategory_TreeNodeMouseClickEventHandler);
}
Outside the designer, I modify it:
this.treeViewCategory.Update();
TreeNode node = this.treeViewCategory.Nodes.Add("Node 1");
node.Name = "Node 1";
node.Nodes.Add("Node 1-Child");
node = this.treeViewCategory.Nodes.Add("Node 2");
node.Name = "Node 2";
node.Nodes.Add("Node 2-Child 1");
node.Nodes.Add("Node 2-Child 2");
this.treeViewCategory.ExpandAll();
this.treeViewCategory.EndUpdate();
I want Node 1 and Node 2 to be functional but not selectable. So clicking on either Node 1 or Node 2 would expand/contract the branch, but the node itself is not highlighted.
private void treeViewCategory_TreeNodeMouseClickEventHandler(object sender, TreeNodeMouseClickEventArgs eventArgs)
{
TreeView treeView = (TreeView)sender;
TreeNode treeNode = eventArgs.Node; // parent or child
String nodeText = treeNode.Text;
// if parent node
if (nodeText.Contains("Node 1") || nodeText.Contains("Node 2")) {
// don't select the node
}
else { // child
}
}
In treeViewCategory_TreeNodeMouseClickEventHandler, I can distinguish between parent and child, but I see nothing that does what I want it do.
Add a handler for the treeview's BeforeSelect event, and cancel the selection there.
// Add unselectable nodes to this collection when you create them
private List<TreeNode> _unselectableNodes = new List<TreeNode>();
private void treeViewCategory_BeforeSelect(object sender, TreeViewCancelEventArgs e)
{
if (_unselectableNodes.Contains(e.Node))
{
e.Cancel = true;
}
}
Unfortunately, as noted in comments, this doesn't prevent selection so much as revert it when the user releases the mouse button. My preference would be for the BeforeSelect event to happen entirely before selection takes place. But there's probably a reason for it.
Handler setup, if you're not doing it via the form builder. This should go in the constructor for your Form. No need for the delegate constructor if treeViewCategory_BeforeSelect has the correct return and parameter types.
this.treeViewCategory.BeforeSelect += treeViewCategory_BeforeSelect;
Node creation:
TreeNode node = this.treeViewCategory.Nodes.Add("Node 1");
node.Name = "Node 1";
_unselectableNodes.Add(node);
node.Nodes.Add("Node 1-Child");
node = this.treeViewCategory.Nodes.Add("Node 2");
node.Name = "Node 2";
_unselectableNodes.Add(node);
Use the Tag property of the node.
The Tag can carry any kind of object.
// for unselectable
...
node0.Tag = false;
...
// for selectable
...
node1.Tag = true;
...
in the selection event you can simply:
if ((bool)node.Tag)
{ ... }

Style change is applied to all children of a TreeView node

I have a TreeView with lots of items, obviously arranged in a tree structure. I am trying to print the parent node in bold and all its children in normal font. However, when I do:
TreeViewItem item = GetParentNode(...);
item.FontWeight = FontWeights.Bold;
this not only changes the parent's style to bold, but also all its children's. I have been looking for properties to disable this recursive update in the TreeView class, but I can't find any. How do I avoid this behaviour?
When you set the font properties it applies it to all children. You could create a new header template and apply it only to the nodes that are parents.
An alternative that has worked in my testing is setting the foreground color:
public MainWindow()
{
InitializeComponent();
StyleParents(MyTreeView.Items);
}
private void StyleParents(ItemCollection items)
{
foreach (var i in items)
{
TreeViewItem tvi = i as TreeViewItem;
if (tvi != null)
{
if (tvi.HasItems)
{
tvi.Foreground = Brushes.Magenta;
StyleParents(tvi.Items);
}
}
}
}
I found that in the WPF TreeView, properties are transferred onto their children if they haven't already been set. The easiest way to avoid this problem (programatically, at least) is to set the font of a child node to the default font as soon as it is created. E.g.
TreeViewItem item = new TreeViewItem ();
item.FontWeight = FontWeights.Normal;
// ...add item to tree
If you now set the FontWeight of a parent node to bold, the children will not change.

How to highlight node in TreeView ? Not only text area, but all row

TreeNode.Select() doesn't work. I want it to be highlighted like
All that I have is
You can use TreeView.FullRowSelect property for this. But remember, it is ignored if ShowLines is set to true.
TreeView.FullRowSelect Property
Gets or sets a value indicating whether the selection highlight spans the width of the tree view control.
public class CustomizedTreeView : TreeView
{
public CustomizedTreeView()
{`enter code here`
// Customize the TreeView control by setting various properties.
BackColor = System.Drawing.Color.CadetBlue;
FullRowSelect = true;
HotTracking = true;
Indent = 34;
ShowPlusMinus = false;
// The ShowLines property must be false for the FullRowSelect
// property to work.
ShowLines = false;
}
protected override void OnAfterSelect(TreeViewEventArgs e)
{
// Confirm that the user initiated the selection.
// This prevents the first node from expanding when it is
// automatically selected during the initialization of
// the TreeView control.
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node.IsExpanded)
{
e.Node.Collapse();
}
else
{
e.Node.Expand();
}
}
// Remove the selection. This allows the same node to be
// clicked twice in succession to toggle the expansion state.
SelectedNode = null;
}
}
follow this link
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.padding?view=netframework-4.7.2

How to select a node of treeview programmatically in c#?

Used treeview.SelectedNode to select a child node. How to invoke treeview.AfterSelect event when a node is selected programmatically?
this.treeView1.SelectedNode = this.treeView1.Nodes[0].Nodes[0].Nodes[0].Nodes[0];
if (this.treeView1.Nodes[0].Nodes[0].Nodes[0].Nodes[0].IsSelected)
{
MessageBox.Show("Node is selected");
}
Apologies for my previously mixed up answer.
Here is how to do:
myTreeView.SelectedNode = myTreeNode;
(Update)
I have tested the code below and it works:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
treeView1.Nodes.Add("1", "1");
treeView1.Nodes.Add("2", "2");
treeView1.Nodes[0].Nodes.Add("1-1", "1-1");
TreeNode treeNode = treeView1.Nodes[0].Nodes.Add("1-2", "1-3");
treeView1.SelectedNode = treeNode;
MessageBox.Show(treeNode.IsSelected.ToString());
}
}
treeViewMain.SelectedNode = treeViewMain.Nodes.Find(searchNode, true)[0];
where searchNode is the name of the node.
I'm personally using a combo "Node + Panel" where Node name is Node + and the same tag is also set on panel of choice.
With this command + scan of panels by tag i'm usually able to work a treeview+panel full menu set.
Call the TreeView.OnAfterSelect() protected method after you programatically select the node.
yourNode.Toggle(); //use that function on your node, it toggles it
TreeViewItem tempItem = new TreeViewItem();
TreeViewItem tempItem1 = new TreeViewItem();
tempItem = (TreeViewItem) treeView1.Items.GetItemAt(0); // Selecting the first of the top level nodes
tempItem1 = (TreeViewItem)tempItem.Items.GetItemAt(0); // Selecting the first child of the first first level node
SelectedCategoryHeaderString = tempItem.Header.ToString(); // gets the header for the first top level node
SelectedCategoryHeaderString = tempItem1.Header.ToString(); // gets the header for the first child node of the first top level node
tempItem.IsExpanded = true; // will expand the first node
private void btn_CollapseAllAndExpandFirstLevelUnderRoot(object sender, EventArgs e)
{
//this example collapses everything, then expands the first level under the root node.
tv_myTreeView.CollapseAll();
TreeNode tn = tv_myTreeView.Nodes[0];
tn.Expand();
}

How to avoid winforms treeview icon changes when item selected

I'm experimenting with a treeview in a little C#/Winforms application. I have programatically assigned an ImageList to the treeview, and all nodes show their icons just fine, but when I click a node, its icon changes (to the very first image in the ImageList). How can I get the icon to remain unchanged?
BTW: The "SelectedImageIndex" is set to "(none)", since I don't really know what to set it to, since the image-index is different for the nodes (i guess?).
UPDATE: Here is the code of the application (I'm using Visual Studio Express 2008):
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
treeView1.Nodes.Add("root","Project", 0);
treeView1.Nodes[0].Nodes.Add("Foo", "Foo", 2);
treeView1.Nodes[0].Nodes[0].Nodes.Add("Fizz", "Fizz", 3);
treeView1.Nodes[0].Nodes[0].Nodes.Add("Buzz", "Buzz", 3);
treeView1.Nodes[0].Nodes.Add("Bar", "Bar", 1);
treeView1.Nodes[0].Nodes[1].Nodes.Add("Fizz", "Fizz", 2);
treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("Buzz", "Buzz", 3);
treeView1.EndUpdate();
treeView1.ImageList = imageList1;
}
}
}
Simply set the SelectedImageIndex for each node to the same value as ImageIndex. So, if you're creating your node programatically:
TreeNode node = new TreeNode("My Node");
node.ImageIndex = 1;
node.SelectedImageIndex = 1;
Or you can specify the whole lot in the constructor:
TreeNode node = new TreeNode("My Node", 1, 1);
You can do the same thing using the design time editor if you're adding nodes at design time. You just need to set the SelectedImageIndex at the node level and not at the TreeView level.
Hi You can also use the below code:
TreeNode Node = eventArgs.Node;
Node.SelectedImageKey = Node.ImageKey;
what can be done here is, we can utilize TreeView's HitTest method which gives the node information at a given point. Then with that info we can reset the Image to previous. Setting SelectedImageIndex to ImageIndex .Like so
var selectedNodeInfo = treeView.HitTest(treeView.PointToClient(Cursor.Position));
selectedNodeInfo.Node.SelectedImageIndex = selectedNodeInfo.Node.ImageIndex;

Categories