Windows form C# change user control by code - c#

I have a windows form and i dont want to make any other windows forms just one windows form and different user controls how can i change between user controls for example hide one and show the other user control programmatically ?
private void Btt_info_Click(object sender, EventArgs e)
{
Frm_Main frm_main = new Frm_Main();
frm_main.Controls["panel1"].Controls.Clear();
UC_Info uc_info = new UC_Info();
frm_main.Controls["panel1"].Controls.Add(uc_info);
}
i added this but it doesnt work

Add a container control (if I remember correctly, there's a containers section in the toolbox?), like a panel. Create usercontrols for what you want to dynamically switch around. So make like a 'HomePage' usercontrol and a 'LoginPage' usercontrol. Dynamically add the usercontrol that you want to display to the container. WHen you want, remove it from the container and add a different usercontrol:
Panel myPanel = new Panel();
LoginPage ctlLoginPage = new LoginPage();
HomePage ctlHomePage = new HomePage();
//add the loginpage to the panel first
myPanel.Controls.Add(ctlLoginPage);
...do stuff...
//remove whatever control is currently in the Panel
myPanel.Controls.Clear();
//add the other control, the HomePage control instead now
myPanel.Controls.Add(ctlHomePage);
..do other stuff...
I usually do it this way so you leave your form itself open to add common controls and stuff that might be shared between your different 'pages'.
EDIT: Note that I normally would add the panel in the designer and not create it dynamically in the code. This was just an example.
EDIT: The interaction between your mainform and usercontrols can be handled in a few different ways, and I am not saying that any of these is the correct method.
You create a static property for your Panel on the Mainform, so that
you can always access it to swap your controls around.
In this example I'll also add a static method for it
enum PanelControlsEnum {HomePage, LoginPage};
public static Panel MyContainerPanel {get;set;}
public static void SwitchPanelControls(PanelControlsEnum selControl){
..put your switch panels code here..
}
Then inside your usercontrol you call a predefined method, something like:
MainForm.SwitchPanelControls(PanelControlsEnum.HomePage);
Another method is to bind the button click event on your mainform
instead of inside the form.
Like This:
HomePage ctlHomePage = new HomePage();
ctlHomePage.Click += MyClickEvent;
myPanel.Controls.Add(ctlHomePage)
...
private void MyClickEvent(object sender, RoutedEventArgs e)
{
..switch user control code here...
}

Create a method that returns a UserControl object. Then put conditions in that method as to which control you want to load at a specific condition and then in your main form code.
UserControl control = GetControlFromMyMethod();
form1.Controls.Add(control);
where 'control' is the returned control from your method.
To remove the existing one you have to loop through the form1.Controls and find out the control and call 'Remove'.
Update:
Mike C has a better idea of adding a panel and loading your desired control on the panel as then it's easy to remove your control and you then don't have to loop through the forms controls to find it and then remove it.

Try this:
this.Controls.Clear();
usercontrol load = new usercontrol ();
this.Controls.Add(load);
load.Show();

you could try this it will definitely help you as it did helped me a lot it short and straight to the point hope that will help

Related

How to dynamically remove a UserControl from the form in c #?

I have a UserControl that is dynamically added to a FlowLayoutPanel. In that same UserControl I have a button to remove itself if the user wants it, obviously at runtime. To eliminate I mean not only to eliminate that tight button, but also the full UserControl that contains the button.
The code of when the UserControl are added dynamically at the moment is as follows:
private void agregaUC() {
UserControl1 UC = new UserControl1();
aux += 1;
UC.Tag = aux.ToString();
flowLayoutPanel2.Controls.Add(UC);
}
The code to eliminate this is on the side of the form, that is, where the UserControl are being added. The button event to remove the UserControl is thrown by code through the operator + =, then there I write the suggestions that you give me.
EDIT: Based on the sample of code you've added, I've modified the below code to work better with what you are looking for. You need to find out how to access the Tag of the control you're trying to remove.
Since you don't have a reference, then you should make sure that the .Tag property can be found, because then you can do something like
foreach (Control c in flowLayoutPanel2.Controls) {
if (c.Tag == "Aux") {
flowLayoutPanel2.Controls.Remove(c);
c.Dispose();
break;
}
}
EDIT
Reading through all the comments everywhere, it seems like this is what's happening. There is a UserControl, inside that user control is a Button (Delete) and the button's Click event is subscribed to by the window, and it's in this event handler that we're trying to remove the UserControl from flowLayoutPanel2
Based on these assumptions, your function should look like this:
void UserControl_Delete_Click(object sender, EventArgs e)
{
Button Delete = (Button)sender;
UserControl UC = (UserControl)Delete.Parent;
flowLayoutControl2.Controls.Remove(UC);
UC.Dispose();
}
This is assuming a lot about the internal structure of everything, as I don't have the code to confirm this will work. It will get you a long ways down the path, though, and should only need a little tweaking based on the actual structure of the UserControl.
You can try something like that.
this.Parent.Controls.Remove(this);
Control.Parent Property.
Remark: Setting the Parent property value to null removes the control from the Control.ControlCollection of its current parent control.
So
this.Parent = null;
Edit
The code is intended to be called from within the user control itself.

Adding event handlers Dynamically to controls within a panel

I've a class which is in a nutshell:
class MyPanel
{
Panel p_panel; //declaring all the elements I need
CheckBox cb_choice;
RadioButton rb_nagy, rb_kicsi;
TextBox tb_db;
public Panel getPanel() {
create(); //creating all the elements I need, then putting them all in the created Panel.
customize(); //setting the panel's size, and the other control's locations within the panel.
return p_panel; //so if I call this method from an other class, this method will return a panel with all the controls inside.
In the other class, I've a list of Panels all of which have been created with the above method.
The layout is done, and it works neatly, I can add as many as I want to the screen. but now I want to add some function to these controls. For example, I want all the radiobuttons disabled unless the checkbox is enabled.
So how can I add a check changed event to all the checkboxes that are in the list of panels?
It seems like you just want to know how to dynamically add EventHandlers to your controls!?
It can be done like this:
cb_choice.CheckedChanged += cb_choice_CheckedChanged;
or if you want to be more explicit (both ways work the same).
cb_choice.CheckedChanged += new EventHandler(cb_choice_CheckedChanged);
And define a handler method:
private void cb_choice_CheckedChanged(object o, EventArgs args)
{
//add code to enable/disable radiobuttons
}

Move controls from the user control to a panel control

I'm trying to write a form theme class library to adjust the form layout in a simple way for any project I'll be working on.
This is basically an idea of what it should look like:
http://www.beaverdistrict.nl/form_layout.png
In essence, the plugin works as follows:
// form class, which inherits the plugin class
class FormToTheme : ThemedForm
{
public FormToTheme()
{
// some code here
}
}
// plugin class itself
class ThemedForm: Form
{
public ThemedForm()
{
// some code here
}
}
Basically I set the FormBorderStyle to None, and drew the layout by code.
But now, the controls that are added can be placed over the custom titlebar, which isn't possible in a normal form if you keep the default FormBorderStyle.
So I figured that I could work around this by automatically adding the controls to the content panel, instead of the usercontrol.
So what I tried to do was this:
private void ThemedForm_ControlAdded(Object sender, ControlEventArgs e)
{
// some simple code to set the control to the current theme I'm using
e.Control.BackColor = Color.FromArgb(66, 66, 66);
e.Control.ForeColor = Color.White;
// the code where I try to place the control in the contentPanel controls array,
// and remove it from it's parent's controls array.
if (e.Control.Name != contentPanel.Name)
{
e.Control.Parent.Controls.Remove(e.Control);
contentPanel.Controls.Add(e.Control);
}
}
But when I try to add a new control in the main form as well as in the visual editor, i get the following error:
child is not a child control of this parent
So my question is: is there a way to work around this error, and move the controls from the usercontrol to the content panel?
Note that I do want this to be automated in the ThemedForm class, instead of calling methods from the main form.
EDIT:
I tried this:
http://forums.asp.net/t/617980.aspx
But that will only cause visual studio to freeze, and then I need to restart.
I know that it is not really appropriate to answer ones own question, however the solution I came up with will take quite some explaining, which will be too much to add in my question with an edit.
So here we go:
Inside the inherited 'ThemedForm' class, I created a private variable, in order to be able to return the variable when the Controls property would be called:
private Controls controls = null;
I set the variable to null, because I need to pass variables to the class in the 'ThemedForm' class constructor. I will create a new instance of the class later on.
Then I created a class to replace the Controls property:
public class Controls
{
private Control contentPanel = null;
private ThemedForm themedform = null;
public Controls(ThemedForm form, Control panel)
{
contentPanel = panel;
themedform = form;
}
public void Add(Control control)
{
if (control != contentPanel)
{
contentPanel.Controls.Add(control);
}
else
{
themedform.Controls_Add(control);
}
}
public void Remove(Control control)
{
if (control != contentPanel)
{
contentPanel.Controls.Remove(control);
}
else
{
themedform.Controls_Remove(control);
}
}
}
I know this class holds far from all functionality of the original Controls property, but for now this will have to do, and if you like, you can add your own functionality.
As you can see in the Add and Remove methods in the Controls class, I try to determine wether the control that needs to be added is either the content panel I want to add the rest of the controls to, or any other control that needs to be added to the content panel.
If the control actually is the content panel, I add or remove it to or from the Controls property of the base class of the 'ThemedForm' class, which is a 'Form' class. Otherwise, I just add the control to the content panel's Controls property.
Then I added the Controls_Add and Controls_Remove methods to the 'ThemedForm' class, in order to be able to add or remove a control from the Controls property of the 'ThemedForm' base class.
public void Controls_Add(Control control)
{
base.Controls.Add(control);
}
public void Controls_Remove(Control control)
{
base.Controls.Remove(control);
}
They are quite self-explanatory.
In order to call the Controls.Add or the Controls.Remove methods from an external class, I needed to add a public property that hid the current Controls property, and returned the private variable that I assigned to the replacing class.
new public Controls Controls
{
get { return controls; }
}
And finally I created a new instance of the Controls class, passing the current 'ThemedForm' class, and the contentPanel control, in order to get it all to run.
_controls = new Controls(this, contentPanel);
After doing all this, I was able to 'redirect' any controls that were added to the UserControl (even inside the visual editor) to the content panel. This allowed me to use the Dock property of any control, and it would dock inside the content panel, instead of over my entire form.
This is still a little bit buggy, because inside the visual editor the docked controls still seem like they are docked over the entire form, but when running the application the result is as I wanted.
I really hope this helps anyone.

WPF: adding a usercontrol to a window

First off, I'm new to WPF and C# so maybe the issue I have is really easy to fix. But I'm kinda stuck at the moment.
Let me explain my problem.
I have a WPF Window and two usercontrols (Controls and ContentDisplayer).
The usercontrol Controls, wich contains some buttons, is added in the XAML of the Window.
Nothing special here.
Window.XAML
<nv:Controls/>
Now, what I want to do is when a user is pressing a button in Controls, ContentDisplayer needs to be added to the Scatterview I have in my Window.
I solved the problem by adding the buttons to the Window, and not using the usercontrol Controls. But this is not what I want.
Window.XAML.CS
private static void Button_ContactChanged(object sender, ContactEventArgs e)
{
object ob = Application.LoadComponent(new Uri(
"NVApril;component\\XAML\\ContentDisplayer.xaml",
System.UriKind.RelativeOrAbsolute));
//Set a unique name to the UserControl
string name = String.Format("userControl{0}",
SurfaceWindow1_Scatterview.Items.Count);
UserControl userControl = ob as UserControl;
userControl.Name = name;
//Add the new control to the Scatterview
SurfaceWindow1_Scatterview.Items.Add(userControl);
SurfaceWindow1_Scatterview.RegisterName(name, userControl);
}
So the real question is: How do I add a usercontrol to the Window by pressing a button in an other usercontrol?
Thanks,
Toner
At the top of the window xaml add
xmlns:d="clr-namespace:SomeNamespace.Usercontrols"
where you these exist already, you can choose the namespace of your control from the intellesence list.
Then where you want to place the control type:
<d:yourusercontrolhere params />
and your usercontrols can be added there.
Within Controls expose an event that is fired when you want to add a new control.
public event EventHandler AddControl;
private void RaiseAddControl()
{
if (AddControl!= null)
{
AddControl(this, EventArgs.Empty);
}
}
Now sink that event in your Window
yourControl.AddControl += ContactChanged
In your window, it sounds like you need to add the event to the instances of Controls.
<local:ContentDisplayer>
...
<nv:Controls AddControl="ContactChanged"/>
...
Then in your ContactChanged event handler you can instantiate a new Controls control and add it to whatever collection you're using like in your Button_ContactChanged event handler above.
Let me know if you need further clarification.
I have no idea what you are trying to do your example,
So you have a control defined thus:
public partial class somecontrolname : UserControl
With your corresponding Xaml file
All you need to do to add it in code to your window is firstly you need a LayoutRoot such as Grid control in the window then just
[mylayoutcontrol].Children.Add(new somecontrolname());
Maybe I got wrong idea what you are trying to do, your example code doesn't make much sense to me, looks like you are trying to load the xaml source file

Building C# .NET windows application with multiple views

I'm rewriting an old application and use this as a good opportunity to try out C# and .NET development (I usually do a lot of plug-in stuff in C).
The application is basically a timer collecting data. It has a start view with a button to start the measurement. During the measurement the app has five different views depending on what information the user wants to see.
What is the best practice to switch between the views?
From start to running?
Between the running views?
Ideas:
Use one form and hide and show controls
Use one start form and then a form with a TabControl
Use six separate forms
Creating a bunch of overlaid panels is a design-time nightmare.
I would suggest using a tab control with each "view" on a separate tab, and then picking the correct tab at runtime. You can avoid showing the tab headers by putting something like this in your form's Load event:
tabControl1.Top = tabControl1.Top - tabControl1.ItemSize.Height;
tabControl1.Height = tabControl1.Height + tabControl1.ItemSize.Height;
tabControl1.Region = new Region(new RectangleF(tabPage1.Left, tabPage1.Top, tabPage1.Width, tabPage1.Height + tabControl1.ItemSize.Height));
What I do is to have a Panel where your different views will sit on the main form.
then create user controls for your different views.
Then when I want to switch between a'view' you dock it to Panel on the main form.. code looks a little like this.
i preffer this because you can then reuse your views, like if you want to open up a view in a tab you can dock your user controls inside tab pages.. or even inherit from
tabpage instead of usercontrol to make things a bit more generic
public partial class MainForm : Form
{
public enum FormViews
{
A, B
}
private MyViewA viewA; //user control with view a on it
private MyViewB viewB; //user control with view b on it
private FormViews _formView;
public FormViews FormView
{
get
{
return _formView;
}
set
{
_formView = value;
OnFormViewChanged(_formView);
}
}
protected virtual void OnFormViewChanged(FormViews view)
{
//contentPanel is just a System.Windows.Forms.Panel docked to fill the form
switch (view)
{
case FormViews.A:
if (viewA != null) viewA = new MyViewA();
//extension method, you could use a static function.
this.contentPanel.DockControl(viewA);
break;
case FormViews.B:
if (viewB != null) viewB = new MyViewB();
this.contentPanel.DockControl(viewB);
break;
}
}
public MainForm()
{
InitializeComponent();
FormView = FormViews.A; //simply change views like this
}
}
public static class PanelExtensions
{
public static void DockControl(this Panel thisControl, Control controlToDock)
{
thisControl.Controls.Clear();
thisControl.Controls.Add(controlToDock);
controlToDock.Dock = DockStyle.Fill;
}
}
Tabbed forms are usually good... but only if you want the user to be able to see any view at any time... and it sounds like you might not.
Separate forms definitely works, but you need to make sure that the switch is seemless...if you make sure the new form appears the same exact size and location of the old form, it will look like it thew same for with changing controls.
The method I often use is actually to pre-setup all my controls on individual "Panel" controls and then show and hide these panels as I need them. The "Panel" control is basically a control container... you can move the panel and all controls on it move relative. And if you show or hide the panel, the controls on it do the same. They are great for situations like this.
The method I often use is actually to
pre-setup all my controls on
individual "Panel" controls and then
show and hide these panels as I need
them.
Instead of making each view a panel within a single form you could make each view a UserControl. Then create a single form and write code to create and display the correct UserControl in the Form and to switch from one to the next. This would be easier to maintain because you will have a separate class for each view instead of a single Form class with 6 panels each with their own controls -- that seems difficult and error prone to maintain.
I would also check out Composite Application Guidance for WPF or Smart Client Software Factory

Categories