I have designed custom user control in c# .This user control is include :
textbox,check box,button.
Now I want to consume designed user control in my project but the problem is I can't access to the textbox,checkbox,button EVENTS when consume user control in my form and there are only EVENTS for user control.how can I make it possible that each object events become accessible when consuming designed user control ?
In your user control set your control like "text-box" Modifiers property to Public.so when you add this user control to your form. you can access to your text box evens:
public Form1()
{
InitializeComponent();
userControl11.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
}
void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("user control textbox.text changed");
}
you might need to manually create public events for the events of those controls which you want to be accessible from outside.
another way is, when initializing those controls in you user control, using public instead of private (which is automatically generated by VS), these code should be located in the xxx.Designer.cs, and they looks likeprivate System.Windows.Forms.Button button1. Then it can be accessed through MyUserControl.button1. But doing so, the entire control will be accessible from outside of your user control, which does not feel very well personally.
I think you should add public events to your custom control class, and make subscribing and unsubscribing there. Just like that:
public event EventHandler ComboboxClick
{
add { _combobox.Click += value; }
remove { _combobox.Click -= value; }
}
For more information see http://msdn.microsoft.com/en-us/library/8627sbea(v=vs.71).aspx
Edit: I would not recomend setting inner controls of your custom control as public properties, because it's a violation of encapsulation principle. You design your own control to do some specific job and clients of the control should stay unaware of its inner composition. Should you change the inner composition of your control in future (switch to some 3rd party textbox control, for example), you would only need to make changes in your custom control class, and its clients would still work properly as if nothing has happend. Here's a good koan about encapsulation =)
Related
I have an issue when it comes working with events and/or delegates. I saw very similar questions but still the real implementation is not clear to me. So please when you answer be more specific so I can try and eventually understand how exactly creating/handling of public/custom events work by doing it in a code I know.
What I have is a User Control which is simply a text box and a button I need to change a record in a database using the value from the text box. I'm using this control for many forms so I need to know which entity exactly I'm using and be able to call it's own save method. Doing all that will be easier if I just can use the click event of the button from my User Control and then call the Save() method of the current form.
This is my User Control :
namespace UserControls.CommonControls
{
public delegate void ClickMe(string message);
public partial class ChangeCode : UserControl
{
public event ClickMe CustomControlClickMe;
public ChangeCode()
{
InitializeComponent();
}
private void btnChange_Click(object sender, EventArgs e)
{
if (CustomControlClickMe != null)
CustomControlClickMe("Hello");
//ToDo fill
//MessageBox.Show("To Do: Write the busieness logic.");
}
public void SetTextBoxMask(MaskedTextBox txtBox)
{
txtChange.Mask = txtBox.Mask;
}
}
}
I post it with the last attempt I made to try and implement what I need.
This is one of the form that need to use the Click event from the User Control and more specific the Constructor because if I understand right there is the place where I have to subscribe for the event :
public MaterialEdit()
{
InitializeComponent();
UserControls.CommonControls.ChangeCode. += new ClickMe(button2_Click);
}
UserControls.CommonControls.ChangeCode - this is how I reach my User Control it's named ChangeCode.
From what you pasted it is not clear that you added ChangeCode control to your form. To use the control and it's events and properties, first you must create new instance to it and add it to the form. This is done:
In designer, by dragging control from Toolbox to the form
In code editor, by invoking control constructor and adding new object to control collection
Only then can you handle event of that object. Let's say that you dropped ChangeCode control to a form, and that Visual Studio named it ChangeCode1. You attach a handled to CustomControlClickMe event like this:
ChangeCode1.CustomControlClickMe += new ClickMe(button2_Click);
Code you pasted (UserControls.CommonControls.ChangeCode. += new ClickMe(button2_Click);) is incorrect for several reasons:
Syntactically, left hand side expression ends with . which makes it incorrect assignment target (UserControls.CommonControls.ChangeCode.)
Event name is not provided, only the control name (you need to end left hand side of assignment with what you want to assign to - .CustomControlClickMe)
You are trying to attach handler to a class and not an object
I created this User Control:
I added that User Control to the main Form and now I want to customize it.
So I will have to add text to those 3 Buttons, text in Label, populate ListBox and setting Click Events for the buttons.
What is the proper way to do that?
I looked around on the web and apparently the way to do it is to add public properties in user control that would expose individual property of control that I need.
Something like:
public string Button1Text
{
get
{
return btn1.Text;
}
set
{
btn1.Text = value;
}
}
If I go this route, I would have to add quite a few public properties to this simple user control.
But isnt it easier just to expose whole control in user control like this?
public Button MyButton1
{
get { return this.btn1; }
set { this.btn1 = value; }
}
That way the Main Form can simply access control and its properties as they are needed.
First method is better from the perspective of encapsulation. Second method causes users (forms) of your control to depend on the view of your control, and this prevents changes to the view in the future.
The first bit of code is the correct way to do it. You will have to create a lot of them but it is the proper way to do it.
The first one is much better where you only create properties for each individual property of the button you wish to be able to access from the Parent control.
If you use the second way, then anyone who wishes to use your control will be able to move and resize individual controls inside your control. Then it really isn't a custom control anymore, but more of a panel that is harder to use than a panel. I can't think of any reason why to be able to allow the Parent to move around individual elements in a subcontrol.
I really had no idea what to title this question.
Assume I have a windows form application. The GUI is complex enough to require two custom user controls, "LeftSide" and "Rightside" which each are composed from various buttons, labels, and maybe even another custom user control.
My question:
I am in in the scope of the "Rightside" control. How would I call a method from the "Leftside" control?
I am using Visual Studio 2008.
The simplest solution is to make a property on the RightSide control of type LeftSide, then set it to the LeftSide instance in the form designer.
You can then call public methods on the property.
However, this is poor design.
Each usercontrol should be a self-contained block that doesn't need to directly interact with other usercontrols.
You should consider restructuring your form.
Exact equivalent with standard WF controls: how to keep the text of one text box in sync with another:
private void textBox1_TextChanged(object sender, EventArgs e) {
textBox2.Text = textBox1.Text;
}
Necessary ingredients: an event on your user control that is fired when something interesting happens. And public properties.
I am embedding usercontrols in a panel and using DevExpress Navigator control to navigate from one to the other. What I am concered about is any implications to this method?
I would give examples of what I am concerned about but then I wouldn't need to ask this question...
I have a primary form, ShellForm that has a docked Navigator Control on the left and a docked Panel Control for the rest. I then dock a User Control, say ucSearchPage, in the Panel when the link is clicked.
public partial class ShellForm : XtraForm
{
private ucSearch searchPage = new ucSearch();
private ucEnrollments enrollmentPage = new ucEnrollments();
private ucGeneral generalInfoPage = new ucGeneral();
private ucContacts contactPage = new ucContacts();
public ShellForm()
{
InitializeComponent();
}
private void ShellForm_Load(object sender, EventArgs e)
{
this.pnlShellHost.DockControl(this.searchPage);
}
private void navSearch_LinkClicked(object sender, DevExpress.XtraNavBar.NavBarLinkEventArgs e)
{
this.pnlShellHost.DockControl(this.searchPage);
}
private void navEnrollment_LinkClicked(object sender, DevExpress.XtraNavBar.NavBarLinkEventArgs e)
{
this.pnlShellHost.DockControl(this.enrollmentPage);
}
The code for DockControl() is as follows -->
public static void DockControl(this Control control, UserControl userControl)
{
userControl.Dock = DockStyle.Fill;
control.Controls.Clear();
control.Controls.Add(userControl);
}
Are there any implications to this approach? Is it just plan stupid?
I am one of those programmers that had to learn to run before walking so I have a tendency to fall flat on my face!
There will be about 30 User Controls in all.
Any insight is welcomed and appreciated!
IMO it is not a bad idea at all to embed user controls. In fact, that is exactly what they were meant for. Because every control inherits from the same base class you can build a tree structure of controls using the Composite pattern. This will allow you to create just about anything you would like.
If you think of a basic web page, this is actually what you are doing anyways: placing one element in another, or embedding them. You can have multiple divs in other divs etc. This is essentially what you are doing when you embed user controls as the user controls render to basic HTML.
Hope this helps.
EDIT: To address the concerns in your comment... I don't think you will have a problem from the data entry standpoint. The reason why is because you are using different user controls for your enrollment control and search control. I'm assuming you are overriding the OnLoad event in each of those user controls right? What happens on post back is that the Search's OnLoad will be hit if the search control was loaded, while the enrollment's OnLoad will be hit if that was loaded.
Because of the polymorphism of the user controls, you can handle the data for those controls separately.
I have a Form and a UserControl. The UserControl has a menu, and the form has a tabstrip (General, Food, Vitamins etc).
In the UserControl, I have the following code: (Form name is frmForm, the tab names in the form are tabGeneral,tabFood, tabVitamins)
frmForm fm=new frmForm();
fm.tabMain.Selected=tabVitamins;
I call these line from the UserControl to capture the tab to get selected on the form, but it does not select the vitamins tab.
Where am I going wrong? I have access specifier as Protected Internal for tabs in the form.
Please advice.
Thanks,
Karthick
When you write new frmForm(), you're creating a completely new instance of frmForm, which is then discarded.
To get the frmForm instance that holds your control, call the FindForm() method and cast to frmForm.
For example:
frmForm myForm = FindForm() as frmForm;
if(myForm != null)
myForm.tabMain.SelectedTab = myForm.tabVitamins;
If the control is on some other form, this code won't do anything.
By the way, Hungarian notation is frowned upon in .Net.
Your form should probably be named something like MainForm.
SLaks has correctly pointed out your fundamental error, and given you a valid example of a way, via a call to the method 'FindForm, to get the Form the UserControl is sited on.
It may be valuable to you to keep in mind that a UserControl (and all Controls) also has a 'Parent property, but, of course, a UserControl could be placed inside another Control on a Form (like your UserControl could be inside a Panel on the Form) : in that case the UserControl's Parent would be the control it's inside on the Form (like, a Panel), not the Form itself, but 'FindForm will do the right thing to get you the Form it's on.
However you are calling a Method every time you use 'FindForm, and "best practice" suggests that what you want to do is to "inject" a reference to the Form into the UserControl at run-time so that it can always access its Form property easily, without calling a 'Method.
In your example, on a practical level, this (calling the Method) may make almost no difference in performance, but, imho, as you get to a place with WinForms and .NET where you might have a UserControl that will need access to its Parent Form very frequently, this will pay off, and it's a better way to structure your code in the long run, for maintenance.
Wes showed you one way you can "embed" (inject) the UserControl's hosting Form : using an overloaded constructor for the UserControl. But that requires you to modify the Designer.cs file in standard WinForms, and I strongly advise you against that, even though it will work. Particularly if you are just "getting your feet on the ground" in .NET, I strongly advise you against modifying it, or anything having to do with the Form's constructor and its internal call to : InitializeComponent();
Also, as you progress with WinForms you are going to meet many situations where you are going to want instances of "objects" (a Control, a Form, an instance of a Class) to contain references to other instances of "objects.
If you can understand and use one simple use of "injection" here, you are going to make progress to make yourself ready to handle more complex .Net programming in the future.
Another way is to put a Public Property in the UserControl that can be set in code from the MainForm. In the UserControl something like :
private frmForm ParentForm;
public frmForm UCParentForm
{
set { ParentForm = value; }
}
So then in your main form's code, perhaps in the Load event like this :
private void frmForm_Load(object sender, EventArgs e)
{
TheUserControl.UCParentForm = this;
}
or when you need to, you set the UserControl's 'ParentForm property once. So you have eliminated using the method 'FindForm().
In this case, if you only want access to a specific control on the UserControl's Parent Form, like a TabControl, you might consider that you want to make the Property you set of type TabControl, rather than Form : the same coding technique shown above can be used in the UserControl :
private TabControl mainFormTabControl;
public TabControl MainFormTabControl
{
set { mainFormTabControl = value; }
}
imho, it is when you are creating UserControls dynamically at run-time, using an overloaded constructor, as Wes suggests, is the best strategy. And using overloaded constructors has many, many others uses in .NET that you'll get into.
good luck !
You should not be creating a new frmForm() inside the user control. You could pass a reference to the frmForm to the user control.
In your user control constructor try something like this.
private frmForm fm;
public YourUserControl(frmForm fm)
{
this.fm = fm;
}
Then you could use.
fm.tabMain.Selected=tabVitamins;
Does that help?