TreeView without checkboxes - c#

I have a TreeView-control in my form which shows a set of nested nodes. Those nodes are just options to be checked or unchecked grouped by a certain attribute present on every single node. Furthermore there´s a second TreeView with the same nesting, however the nodes within that list are just for information. That is user shouldn´t be able to check or uncheck them at all.
So I tried to disable the checkboxes for every node within the second tree by setting the Checkboxes-property to false. I also registered for the BeforeCheck-event:
m_treeView.BeforeCheck += m_inactiveValidationsTreeView_BeforeCheck;
m_treeView.Checkboxes = false;
// ...
private void m_inactiveValidationsTreeView_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
e.Cancel = false;
}
However all items still have the checkboxes. How can I disable checkboxes for all my nodes (not just making them greyed out but just making them invisible).

Look here
There is no straight way for this. A TVM_SETITEM message needs to be sent to the treeview control, set TVITEM structure's state field to 0, and TVITEM's hItem field to the treenode's handle.

Related

Visibility of Form Components when Enabled is false C#

I have a form with labels and other components, picture boxes, panels, etc.. When I am doing Form.enabled = false; (because I have another form on top of it) the labels are not showing even though the visibility of the components is set to true; Any ideas?
I didn't include code because I'm not sure what to include!
Thanks for any help!
Edit: After what Joel Etherton said, I tried using this event:
private void label1_VisibleChanged(object sender, EventArgs e)
{
label1.Visible = true;
}
This is giving me a StackOverflowException.. maybe this is infinitely trying to override the parent control visibility.. What can I do please?
Check the element's parent objects (and follow it up the tree). Usually this is caused by a parent being set to Visible = false;. Visibility settings for a particular control will still register as true, but when the page is actually rendered it will stop producing controls at any parent level whose visibility is false.
Edit:
First you should find the root cause of the problem. This isn't a code issue so much as an expectation issue. A control is expected to be visible, but you've created a condition where that is not possible. I think you'd be better served by trying to find out what condition is causing a parent control to have a false visibility. Most likely you'll find either there is a logical problem with forcing a parent's visibility or a design problem where your "visible" control is being placed in the wrong root container. However, if you just want to brute force the visibility of parents you can have a recursive method do it:
private static void SetAllParentVisibility(bool visible, Control ctrl)
{
ctrl.Visible = visible;
if (ctrl.Parent != null)
SetAllParentVisibility(visible, ctrl.Parent);
}
Also, treat the above method as psuedo-code. I haven't tested it out, and the type Control may need to be altered to be able to adjust to different parent types.

How to group Groups of radio buttons in Windows forms

I have a form with a number of radiobuttons where only one should be selected at a time.
Some of the radiobuttons are connected and need to bee explained by a header. For this i put them in a Groupbox. But then is the radiobuttons inside the groupbox no longer connected to the ones outside and its possible to select two off them.
Is there a way to connect the radiobuttons so they all react on eachother? Or is there a better way to group and explain the radiobuttons then using a groupbox?
It is the designed behavior of a RadioButton to be grouped by its container according to MSDN:
When the user selects one option button (also known as a radio button)
within a group, the others clear automatically. All RadioButton
controls in a given container, such as a Form, constitute a group. To
create multiple groups on one form, place each group in its own
container, such as a GroupBox or Panel control
You could try using a common eventhandler for the RadioButtons that you want linked and handle the Checking/UnChecking yourself, Or you can place your RadioButtons on top of your GroupBox, not adding them to the GroupBox then BringToFront.
This is possible, but it comes at a high price. You'll have to set their AutoCheck property to false and take care of unchecking other buttons yourself. The most awkward thing that doesn't work right anymore is tab stops, a grouped set of buttons has only one tabstop but if you set AutoCheck = false then every button can be tabbed to.
The biggest problem no doubt it is the considerable confusion you'll impart on the user. So much so that you probably ought to consider checkboxes instead.
In windows forms I don't think there is an easy way (as in setting a property such as GroupName) to group radiobuttons. The quickest way would be to simply group the radiobuttons in a collection and listen to the checkedchanged event. For example:
var rbuttons = new List<RadioButton>{ radioButton1, radioButton2, radioButton3, radioButton4 }; //or get them dynamically..
rbuttons.ForEach(r => r.CheckedChanged += (o, e) =>
{
if (r.Checked) rbuttons.ForEach(rb => rb.Checked = rb == r);
});
If any of the radiobuttons in the list is checked, the others are automatically unchecked
I solved this by handling the CheckChanged event.
private void radio1_CheckedChanged(object sender, EventArgs e)
{
if (radio1.Checked)
{
// do stuff
radio2.Checked = false;
}
}
private void radio2_CheckedChanged(object sender, EventArgs e)
{
if (radio2.Checked)
{
// do stuff
radio1.Checked = false;
}
}

TreeView vertical scrollbar does not expand to the last node, last node is hidden?

I am experiencing an odd behaviour from a TreeView control.
As you can see, the last node in the treeview is somehow hidden (although I can select it with keyboard up/down arrow keys) and the scroll bar does not expand to it. In the picture the blue line you see is the selected node that is hidden but luckily still a bit of highlight is visible!
Even when I press pagedown or END keys, I cannot select the last node!
I tried to change height of the treeview control to match the height of nodes but still no success! My treeview is inside a 'panel'. could it be the problem?
UPDATE
I am not doing something extraordinary. I just populate with a loop over a List<> (using suspend and resume before and after loop) then the treeview will be populated normally.
public class MyNode
{
public string Name {get;set;}
public string Result {get;set;}
}
//suspending code here (dont have access to paste it here)
foreach(MyNode node in myNodeList)
{
TreeNode tn = new TreeNode();
tn.Text = node.Name;
tn.Name = node.Result;
treeView.Nodes.Add(tn);
}
////unsuspending code here (dont have access to paste it here)
Later I allow user to press a button to highlight the nodes that have result set to 'fail':
foreach(TreeNode node in treeView.Nodes)
{
if (node.Name.ToString() == "fail") node.BackColor = Color.Red;
}
After this, the last node in the treeview is going hidden!!!
FIX
I used BeginUpdate() and EndUpdate() methods and the problem is gone!!!
You should use SuspendLayout() and ResumeLayout() before and after adding the nodes.
This will solve the problem.
You may also want to use BeginUpdate() before SuspendLayout() and EndUpdate() after ResumeLayout().
Edit: This is a known issue in .Net 2.0.
Disabling visual styles will help.
If you don't want to disable visual styles you could add an empty node to the end of the tree (when there are more than fit in the visible treeview control).
See the issue at MS: https://connect.microsoft.com/VisualStudio/feedback/details/94021/treeview-does-not-display-the-last-node
I found out that I have to user treeView.BeginUpdate() and treeView.EndUpdate() methods before and after populating the tree view and also making any changes to its nodes.

How do I change a display using TreeView?

I'm trying to change a panel to a specific form (as this is the only way I can fathom it) based on the selected TreeView node. For example, in Visual Studio, if you right-click on "Solution 'solutionname' (1 Project)", click 'Properties', it comes up with a tree list on the left side. When you click on a selection, the right pane changes.
I've searched continuously for hours the previous few days and only found a tutorial showing how it can affect a webBrowser control.
This is a farfetched example that I can understand:
private void tree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
treeNode nName = e.Node;
//For testing:
string pg = "";
pg = nName.Tag;
if (pg == "Form2") display = Form2;
}
Display is a panel. I know this is absolutely wrong, but I couldn't find any proper method using my search terms.
You will need to set Visible on all your panels to false, except for the one you want to display which will be set to true.
WinForms does not have any particularly nice way of setting this up. You could set the Tag property of each node to be a reference to the panel (this has to be done programmatically - the designer won't let you do it), then iterate through the entire tree view to set ((Panel)node.Tag).Visible = false followed by ((Panel)e.Node.Tag).Visible = true or you can maintain the list separately. If you don't have many panels, a switch/if-else block may be okay, too.

Selecting a TreeView Item without invoking SelectedItemChanged?

In my app, I have a group of 3d objects and they're exposed to the user through a TreeView. When a user selects an item in the TreeView, an SelectedItemChanged event is fired, the corresponding 3d object is set to be selected and is highlighted in the 3d render window. This works fine.
What I'm having trouble with is the reverse. In a section of my code, I programatically set the selected 3d object in the scene. I want to reflect the currently selected object in the TreeView, so I run through the items until I find the corresponding one. But once I get to it, I can't find a way to make the item appear selected without having SelectedItemChanged being called, which is not what I want.
Is there a way to do this?
Thanks!
I take it you want to suppress the code in your event-handler? If so, a common way of doing this is with a boolean flag (or sometimes an int counter):
bool updatingSelected;
void SomeHandler(object sender, EventArgs args) { // or whatever
if(updatingSelected) return;
//...
}
void SomeCode() {
bool oldFlag = updatingSelected;
updatingSelected = true;
try {
// update the selected item
} finally {
updatingSelected = oldFlag;
}
}
Would it be appropriate to remove the TreeView's SelectedItemChanged event handler temporarily, and re-add it once you've performed the necessary operations? I haven't tried it myself, but it's the only other thing I can think of (Marc Gravell beat me to my original answer - I've done THAT before ;) ).
Good luck!

Categories