i'm developing a windows form application.in the form, the left part is a tree menu, and the right part is show area. how can i change the show area according to what i click on the tree menu.
(source: 126.net)
i use treenode class to implement treemenu like this:
System.Windows.Forms.TreeNode treeNode27 = new System.Windows.Forms.TreeNode("basic operation");
what i try to do is use several panels. each panel bounds to a menu item. by setting the visible property, i can achieve that goal. but it is too inconvenient.especially when i try to design each panel.
any good suggestion?
You could design each "Panel" as a new User Control. That way you can design all of the "panels / areas" on their own, independently of the Main Form.
On your Main Form, create a single panel for the right hand side area and add all of the controls to that one panel.
Then when the TreeNode selection event happens you can set all the user controls to .Visible = false; except for the one you are showing and set that to .Visible = true; and .Dock = DockStyle.Fill;
What you need is an event handler that will be called at the time of the user clicking the treeview (Use TreeView from the toolBox). You can do that by selecting the treeview on the design page and under properties click on Events. Then select NodeMouseDoubleClick or NodeMouseClick depending upon what you want. Below is a code that captures the values selected...Enjoy...;)
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (treeView1.SelectedNode.Level == 2)
{
//text on the first level
string text = treeView1.SelectedNode.Text;
}
else if (treeView1.SelectedNode.Level == 1)
{
//text on the second level
string text = treeView1.SelectedNode.Text;
}
}
Related
I'm trying to make it to where a panel becomes visible and it sent to the front so it can be seen and interacted with, like this.
private void SettingsButton_Click(object sender, EventArgs e)
{
SettingsPanel.Visible = true;
SettingsPanel.BringToFront();
}
The problem is that after clicking a few of the buttons, it will either display the wrong panel or none at all. Is there a way to fix this?
EDIT: Before y'all ask, i'm using WinForms.
OK, so I was wrong, WinForms is smarter than I thought. Here's a test you can do. I'm not exactly sure what you are trying to do, but this should help you along. To start, we're going to build a small WinForms app. With one exception, we aren't going to set any properties of the controls we drop on the screen:
Create a new WinForms app
In the designer, drop a Panel (which will be named panel1) on the form
In the properties pane, set the BorderStyle to FixedSingle (that's the only property we are going to set)
Make two copies of that panel (panel2 and panel3). Position them so that panels do not overlap at all.
On each panel drop a couple of controls (I put labels (labels 1-3) and textboxes (also 1-3)) on each one
Beside each panel (arranged so that there is no overlap) drop three buttons on the form (buttons 1-3) make it so that visually, each button is associated with the similarly numbered panel
Duplicate panel3 including its contained controls (so that you get panel4, label4 and textbox4). Position the duplicate so that it significantly overlaps panel 3
Now we're going to look at the code that the designer creates for your form. Don't mess with this code (you can, but if you don't know what you are doing, it can turn out bad - and, we're keeping this simple).
In the Solution Explorer click the unfilled triangle to the left of Form1.cs. Note that it rotates and turns solid. Also note that Form1.Designer.cs is displayed. That's a normally hidden source file that contains all the designer created code that corresponds with the form and the controls you dropped on it.
Open Form1.Designer.cs
Click the little grey plus sign icon next to Windows Form Designer generated code
Inspect the file. Note that every action you did in the designer has a corresponding line of code in the Designer.cs file (more or less)
Look at the code for one of the panels (say panel1).
See that it includes:
this.panel1.Controls.Add(this.textBox1);
this.panel1.Controls.Add(this.label1);
Scroll all the way down to the Form1 code and see that the panels and buttons get added to the Form's Controls collection:
Like:
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel4);
this.Controls.Add(this.panel3);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel1);
Note that the order is reversed. The order is important, it sets the Z-Order (i.e., what overlaps what) for the form and the controls on the form.
Wiring up the buttons
Select all three buttons and press <Enter>. This will open the Form1.cs file and generate three button click handlers that you can fill in.
Use this code for the three button handlers:
private void button1_Click(object sender, EventArgs e) {
var wasVisible = panel1.Visible;
panel1.Visible = !wasVisible;
}
private void button2_Click(object sender, EventArgs e) {
panel2.BringToFront();
}
private void button3_Click(object sender, EventArgs e) {
panel3.BringToFront();
}
The first one will toggle the first panel's visibility (I put in an extra variable so you can set a breakpoint and see what's going on). The second one brings panel2 to the front, changing its Z-Order (it's called Z-Order because the position on the screen is measure in X and Y, which the overlap position is related to the "depth" of the screen, or the Z-coordinate). The last one does the same thing to panel3.
Run the program.
When you press the first button, the first panel and its controls disappear (this surprised me, WinForms is smarter than I thought)
When you press the second button, nothing appears to happen. This is because the only thing that panel2 intersects is the form, and panel2 already covers the form, so you don't see any effect. (and because WinForms is smarter than I thought)
When you press the third button, panel2 (and it's controls) jump to the front of the stack of controls, covering the intersecting part of panel4.
Does this help you understand how Visible and BringToFront() work?
What you're describing is similar to a TabControl alternative. Here's an example:
You can manage the current panel simply by making it visible and docked to fill. Hide the other panels.
public partial class FormTabsAlternative
: Form
{
int m_current = 0;
List<Panel> m_tabs = new List<Panel>();
public FormTabsAlternative()
{
InitializeComponent();
AddTab(pnl1);
AddTab(pnl2);
AddTab(pnl3);
AddTab(pnl4);
SetUpTabsAndButtons();
}
private void AddTab(Panel pnl)
{
m_tabs.Add(pnl);
pnl.Dock = DockStyle.Fill;
}
private void OnLeftClick(object sender, EventArgs e)
{
if (m_current > 0)
{
m_current--;
SetUpTabsAndButtons();
}
}
private void OnRightClick(object sender, EventArgs e)
{
if (m_current < m_tabs.Count - 1)
{
m_current++;
SetUpTabsAndButtons();
}
}
private void SetUpTabsAndButtons()
{
for (int index = 0; index < m_tabs.Count; index++)
{
var panel = m_tabs[index];
panel.Visible = index == m_current;
}
btnLeft .Enabled = m_current > 0;
btnRight.Enabled = m_current < m_tabs.Count - 1;
}
}
i'm using telerik control.
So i want to ask,
In winforms application ,Is it possible to add more than one panel in same location and display one at a time just like show/hide property.
Make sure you have placed all panel control in same container or form. then you can use Visible property to show and hide panel. BringFront and SendToBack function will be used to bring panel on top or send it to back. If you have placed any panel in another panel then that will be disappeared when you Hide parent panel. So, Make sure all panels' parent control must be same. To determine the parent control simply select that panel and press escape key to select their parent.
private void LoadPanels()
{
panel1.Location = new Point(10,10);
panel2.Location = new Point(10,10);
panel3.Location = new Point(10,10);
panel4.Location = new Point(10,10);
panel5.Location = new Point(10,10);
VisiblePanel("panel1");
}
private void VisiblePanel(string panelName)
{
string[] panels = new string[]{"panel1","panel2","panel3","panel4","panel5"};
for (int i=0;i<panels.Length;i++)
this.Controls[panels[i]].Visible = (panels[i] == panelName);
this.Controls[panelName].BringToFront(); //Not required you can remove this line.
}
Here's a slightly different approach you might want to consider...
Are you wanting to be able to programmatically select the contents of a rectangular area at runtime, selecting among various controls to display? If so, you could use a custom TabControl which has its tabs (not the pages) hidden.
Then you can select which page is displayed by programmatically changing its SelectedIndex property at runtime.
Doing it like this means that your form editor will show a normal tab control, which allows you to much more easily add the content to each page - but at runtime the tabs will be hidden from the user; they will just see the contents of the currently selected page.
See Hans Passant's answer here for how to create such a custom tab control.
(However, you might also want to override the OnKeyDown for the custom tab control in order to ignore Ctrl-Tab.)
Here is my form
If I click on "Add" on the first panel I want to create "Strategy1_2" just below the first and shift all others panels down.
If I click again I want to create Strategy1_3 (...)
I know how to create a button but not how to duplicate a entire panel.
Here is my code for a button is it far from this procedure ?
private void addstrat1_i_Click(object sender, EventArgs e)
{
panel3strat.Width += 200;
Button addstrat1_2 = new Button();
addstrat3_2.Size = new Size(210, 41);
addstrat1_2.Location = new Point(31,89);
addstrat1_2.Visible = true;
panel1strat.Controls.Add(addstrat3_2);
}
The best way would be that you create a UserControl for your strategy panel. You can then insert the UserControls to a FlowLayoutPanel. This will resolve your issue with placing controls exactly and to create a copy of some panels.
Be aware that you can run out of resources (e.g. windows handles) when adding to much controls on your form. This can be solved by only showing a certain amount of controls and shifting the data through this "fixed" controls while scrolling.
I recommend having two methods: CreatePanelBlock() that will issue a UserControl that you'll add to your container, and BindPanelWithData(...) that will setup the dependencies.
Remember, you may make your panel as a custom control.
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;
}
}
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.