C# Populating a TreeView with TabControl - c#

So I've been able to populate a TreeView with the tabnames in WPF/XAML binding but haven't done this before with C# Windows Forms.
I want to have the treeview display the project name based on what file is open and then tabcontrol names below it (these are static -- one is called editor and the other fields).
I'll add a context menu later, but the sole purpose would be to make the tabs visible based on their state with click events from the treeview.
My problem is I can't figure out how to associate them in the treeview. I found this code, can anyone tell me if I'm on the right track here?
private void treeView1_AfterSelect(Object sender, TreeViewEventArgs e)
{
// Set the visibility of the tabpages from the treeview
if ((e.Action == TreeViewAction.ByMouse))
{
if (e.Node.Name == "Editor")
{
this.editForm.tabControl1.SelectedTab = editForm.Editor;
}
if (e.Node.Name == "Fields")
{
this.editForm.tabControl1.SelectedTab = editForm.Fields;
}
}
}

You could use the TreeNodes's Tag property to hold the associated Tab Name.
if (e.Action == TreeViewAction.ByMouse)
{
TabPage p = tabControl1.TabPages[e.Node.Tag]
tabControl1.SelectedTab = p;
}

Related

Calling a specific UserControl based on which node is checked in a TreeView structure

In my Windows Form, there are two User Controls, placed one on top of the other.
I also have a TreeView Structure (TreeView1) that has a root node (with two child nodes itself, with check boxes).
Basically, I wish to make only one User Control visible when the Tree View Node corresponding to that User Control is checked.
This is the code that I've written to respond to the checking event:
private void TreeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
string Case;
Case = e.Node.Name;
switch (Case)
{
case "Call_UC1": //Name of the first node of TreeView Structure
UC1.BringToFront(); //UC1 - object of the User Control 1
UC1.Visible = true;
break;
case "Call_UC2": //Name of the second node TreeView Structure
UC2.BringToFront(); //UC2 - object of the User Control 2
UC2.Visible = true;
break;
default:
break;
}
}
Problem is, the User Controls are not responding when I check any of the check boxes of either node. Nothing is happening. I'm guessing that my implementation of the TreeView Event Handler was not proper. Could anyone help me out?
AfterCheck() also fires when a node is UNCHECKED...you need to check for this. Also, do you have code in place that prevents both of the boxes from being checked at the same time? Otherwise, which one should be in front? Whatever one was last checked?
...and what happens if both are not checked after previously having been checked? Should the UserControls be invisible?
So many questions...
This ~might~ be what you're after:
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Node.Checked)
{
if(e.Node.Name == "Call_UC1")
{
UC1.Visible = true;
UC1.BringToFront();
}
else if (e.Node.Name == "Call_UC2")
{
UC2.Visible = true;
UC2.BringToFront();
}
}
}

Show property editor by click on property text box in PropertyGrid

I am creating a touch application on a no-keyboard pc, where I use a PropertyGrid to manage classes to store / save the app configuration.
I need to edit the propertyline's rows with a custom keyboard that I created (not the system's) setting the class as UITypeEditor
Now the custom keyboard is showed when right button is clicked.
Is it possible to show when on the row start edit (like textbox Enter event),
or when the row is selected ?
The editor control which you see in PropertyGrid is a GridViewEdit control which is a child of PropertyGridView which is a child of the PropertyGrid.
You can find the edit control and assign an event handler to its Enter event. In this event, you can find the SelectedGridItem and then call its EditPropertyValue method which is responsible to show the UITypeEditor.
private void propertyGrid1_SelectedObjectsChanged(object sender, EventArgs e)
{
var grid = propertyGrid1.Controls.Cast<Control>()
.Where(x => x.GetType().Name == "PropertyGridView").FirstOrDefault();
var edit = grid.Controls.Cast<Control>()
.Where(x => x.GetType().Name == "GridViewEdit").FirstOrDefault();
edit.Enter -= edit_Enter;
edit.Enter += edit_Enter;
}
private void edit_Enter(object sender, EventArgs e)
{
var item = this.propertyGrid1.SelectedGridItem;
if (item.GetType().Name == "PropertyDescriptorGridEntry")
{
var method = item.GetType().GetMethod("EditPropertyValue",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
var grid = propertyGrid1.Controls.Cast<Control>()
.Where(x => x.GetType().Name == "PropertyGridView").FirstOrDefault();
method.Invoke(item, new object[] { grid });
}
}
Note: For modal editors the Enter event is annoying and repeats over and over again. To avoid this you can use Click event of the control.
Also as another option you can rely on SelectedGridItemChanged event of PropertyGrid and check if e.NewSelection.GetType().Name == "PropertyDescriptorGridEntry" then call EditPropertyValue of the selected grid item using reflection.

C# Get a selected TabControl tab in Visual Studio WinForm

I'm looking for the method which returns a bool on whether or not a tab in a TabControl is selected. I would think there would be something like tabPage1.IsSelected() but there isn't. I found this: TabControl.SelectedTab Property However, this SelectedTab property is absent from my WinForms class for some reason. Not sure if it's been taken out or what. Thanks.
I tried below code to know which tab is selected.
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedTab == tabControl1.TabPages["operationstabPage"])
{
//add your code here
}
}
To get the selected tab in tab control, you can use -
var selectedTab = this.tabControl1.SelectedTab;
So you can do -
bool tabSelected = this.tabControl1.SelectedTab == this.tabPage1;

Remove something added by a particular event - c#

I have a piece of code that will add the selected item of a combobox to a listbox when a checkbox is checked. I would like to remove that selected item to be removed from the listbox when the checkbox is unchecked.
My problem is I cant simply repeat the code for removal to be the same as add because the combobox selection will different or empty when unchecked.
This is how it currently looks:
private void CBwasher_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked == true)
{
listBox2.Items.Add(comboBox1.SelectedItem);
}
if (checkBox1.Checked == false)
{
listBox2.Items.Remove(comboBox1.SelectedItem);
}
So I need a way of removing whatever was added by that check change instead of removing the selected index of the combobox. Please consider that there may be multiple lines in the listbox added by multiple different checkboxes.
You simply need to store the added item and remove it.
private object addedItem;
private void CBwasher_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
addedItem = comboBox1.SelectedItem;
listBox2.Items.Add(addedItem);
}
else
{
listBox2.Items.Remove(addedItem);
}
}
You may also need to check SelectedItem is null before adding/removing the item.
Focusing on the part where you said there might be multiple different checkboxes,
you need to store one item per checkbox.
You can write your own child class of the checbox control to add this feature, or simply use the Tag property.
You can also indicate which checkbox is linked to which combobox in the same way. Either child class or use the Tag property.
In my example, I'll assume you've referenced the combobox from the checkbox using the Tag property.
You can do it manually like this
checkBox1.Tag = comboBox1;
or hopefully you can automate it if you are generating these on the fly.
Here is the general idea of how the checkbox event should look.
The event is is utilising the sender argument, which means you should hook up all your checkboxes CheckedChanged events to this one handler. No need to create separate handlers for each.
private void CBwasher_CheckedChanged(object sender, EventArgs e)
{
var checkBox = (CheckBox)sender;
var comboBox = (ComboBox)checkBox.Tag;
if (checkBox.Checked && comboBox.SelectedItem != null)
{
listBox2.Items.Add(comboBox.SelectedItem);
comboBox.Tag = comboBox.SelectedItem;
}
if (!checkBox.Checked && comboBox.Tag != null)
{
listBox2.Items.Remove(comboBox.Tag);
}
}

How to set radio buttons in a nested group box as a same group with radio buttons outside of that group box [duplicate]

This question already has answers here:
Grouping Windows Forms Radiobuttons with different parent controls in C#
(4 answers)
Closed 5 years ago.
I have winform application (.NET 4.0)
Is there any way to manually set a group of radio buttons?
I have four radio buttons, two of them inside of a group box and the other two outside of that box. How can I set all of them to the same group?
This might have been answered in another post, it sounds the same:
Grouping Windows Forms Radiobuttons with different parent controls in C#
This was the accepted solution:
I'm afraid you'll have to handle this manually... It's not so bad
actually, you can probably just store all the RadioButton in a list,
and use a single event handler for all of them:
private List<RadioButton> _radioButtonGroup = new List<RadioButton>();
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = (RadioButton)sender;
if (rb.Checked)
{
foreach(RadioButton other in _radioButtonGroup)
{
if (other == rb)
{
continue;
}
other.Checked = false;
}
}
}
Edit: Here's another question asking the same thing:
Radiobuttons as a group in different panels
I'm not sure if this is possible in WinForms.
According to the docs:
All RadioButton controls in a given container, such as a Form, constitute a group.
You could create the class yourself though
public class ButtonGroup {
private IList<RadioButton> radiogroup;
public ButtonGroup(IEnumerable<RadioButton> selection) {
radiogroup = new List<RadioButton>(selection);
foreach (RadioButton item in selection) {
item.CheckedChanged += uncheckOthers;
}
}
private void uncheckOthers(object sender, EventArgs e) {
if (((RadioButton)sender).Checked) {
foreach (RadioButton item in radiogroup) {
if (item != sender) { item.Checked = false; }
}
}
}
}
GroupName is property used in Web.UI.RadioButton to group a set of radio butons as one unit. All radiobuttons with same GroupName value will form a group.
This functionality however is not available in winforms.
So the only way to group radiobuttons in winforms will be to keep them together in the same container (generally a groupbox).
There is a property called "validation" group or something like that that groups all the controls into one validation. Only one of them is checked only. Other ones uncheck.

Categories