i wanted to disable form control from class library, means i added one class named as clsInit method & i called this method when i'm loading the form in main project,so i need find the control which one i wanted to disable.
Is it possible to find loaded form controls in class library?
Form.Controls property is what you need.
You can pass the reference of your form into your library, and access its controls via Controls property.
You may create an object of your form, as:
MyForm frm = new MyForm();
...then select the controls to be disabled:
foreach (Control control in frm.Controls)
{
if(control.Name == "cboSomeDdn")
control.Enabled = false;
}
and then load the form (this one :
frm.Load()
or
frm.Show()
If this is a one form application, you may also set this as a starting point:
Application.Run(frm);
Please use this answer as a starting point and not as a copy-paste
solution. Also ensure to follow best-practices of development in the
language of your choice.
Hope this helps!
Vivek
Related
I need to make a UserControl that can be used for multiple projects. But it needs to be a Form so the user can just add a reference to the library and call the form.
I've seen third party companies like Telerik and DevExpress use custom forms that can be added to a project.
How would I accomplish this? I've been looking through SO and various posts from Google, but have not been successful in my searches.
EDIT I was assuming it had to be a UserControl for some reason. But it doesn't. I took the suggestion of just adding a form and calling it from that namespace. Works exactly as needed. Thanks everyone.
Just create the form in your library, make it public, and you can call it from anywhere.
Methods to create and call form are:
YourFormClassName FormForUser = new YourFormClassName();
FormForUser.Show();
FormForUser.ShowDialog();
Maybe I don't understand. If I do, then it's straight forward.
Add a project (ProjectWithReusedForm) to your solution that contains the form to be reused.
Add a reference to ProjectWithReusedForm in the second project where you want to use the form
Add a 'using ProjectWithReusedFormNamespace' to the code where you want to use the form
You then can add the statement ReusedForm myForm = new ReusedForm();
You can create BaseForm (either add it into a project directly by adding .cs file or reference something compiled - class library to example). Then just add a new form to a project
namespace MySolution
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}
and chang Form to BaseForm
public partial class Form1 : BaseForm
Just Create form with all controls. and create empty user control
Ex:
do this code inside usercontrol constructor after initialize function
dim obja as new RegForm()
obja.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
obja.Visible = true
obja.Dock = System.Windows.Forms.DockStyle.Full
me.Controls.Add(obja)
You have to be careful here. Your tag lists winforms, so I am assuming you are using .net and UserControls. Winforms only allows a single form per page. You can add multiple UserControls to a page. If you go with the base form route, the programmer will have to add everything else to your base page. UserControls will offer a little more flexibility in that they can be added to an existing page.
Currently I have a C# program with a windows form and then a user control template put onto the form. The user control template is really just used as a placeholder. I have a series of other controls which inherit from this user control template.
Each of those controls have navigation buttons like 'Continue' and 'Back' on them and each control knows which control needs to be loaded next. However what I need to figure out is an easier way to have variables that are global to these controls.
The only workaround I have is that I pass the form to each control when they are loaded and use variables inside of the form to read and write to. What would be the proper way to have each of these user control screens be built off of a base control which contained objects all of the controls could get to?
Sorry for the rambling nature of the post but I've been thinking about this problem all morning.
Here is some of the code:
Most of what I have written was based on hiding and showing the user controls so that content in the controls wouldn't be lost during navigation. I won't be needing to do that as eventually it will be loading the fields of data from a database.
Code for initially loading control from form click:
conTemplate1.Controls.Clear();
conInbound Inbound = new conInbound(this);
Inbound.Dock = DockStyle.Fill;
Inbound.Anchor = (AnchorStyles.Left | AnchorStyles.Top);
conTemplate1.Controls.Add(Inbound);
Code for Continue button inside of one of the controls:
if ((Parent.Controls.Count - 1) <= Parent.Controls.IndexOf(this))
{
UserControl nextControl = new conPartialClear();
nextControl.Dock = DockStyle.Fill;
Parent.Controls.Add(nextControl);
this.Hide();
Parent.Controls[Parent.Controls.IndexOf(this) + 1].Show();
}
else
{
this.Hide();
Parent.Controls[Parent.Controls.IndexOf(this) + 1].Show();
}
The best-practice for communicating from a control to a parent is to use events, and for communicating from a parent to a control is to call methods.
However, if you don't want to or can't follow this practice, here's what I would recommend.
Each UserControl has a ParentForm property that returns the Form that contains the control. If you know that the UserControl will always be attached to MyParentForm, you just cast the ParentForm and then you can access all public controls, methods, etc.
Here's what I mean:
public class conTemplate
{
public MyParentForm MyParentForm
{
get
{
return (MyParentForm)this.ParentForm;
}
}
}
This way, you can easily access any public members of MyParentForm. Your conInbound class could have code such as this.MyParentForm.GlobalSettings.etc..., and could even have access to any public controls.
I'm not totally sure I understand your problem. It sounds like you want the user control to "do something" with it's parent form. If that's the case, you may want to consider adding events to the UC and then handle them on the form itself.
Basically, for your UC's "continue", you'll have an event that's fired when it's pressed. You'll want to handle that in your form. I'm not real sure about the syntax from memory, or I'd work something out for you code-wise. But I think that's the route you'll want to take. Think of your UC like any other windows form control. If you add a button to your form, you assign it it's event method. Do the same with the UC.
I found this and thought it may be helpful. Scroll down to where it talks about UC's and events.
http://www.akadia.com/services/dotnet_user_controls.html
Hope this helps.
EDIT after new info from OP.
You could declare a global variable inside the UC of type yourForm and then set that variable to the ParentForm at run-time, if I'm understanding you correctly.
So, inside your UC Class, you could do:
private parentFormInstance;
then inside the constructor of the UC, you could set it as such:
parentFormInstance = this.ParentForm; (or whatever the property name is).
This allows you at design-time to use:
parentFormInstance.DoSomething();
without the compiler yelling at you.
Just basic advice, but if you can go back and make it easier on yourself, even if it takes some additional time re-working things, it'd be worth it. It may save you time in the long run.
I have two forms in C# Window application as frm_Stock.cs and frm_Purchase.cs.
I want to use some controls of frm_Stock in the frm_Purchase.Is it possible?IF yes then how can i do this please give me suitable example.
Thanks in advance
You will have to pass a reference to the controls/form when constructing the other form, and use that reference. A rough example,
frm_Stock = new StockForm();
frm_Purchase = new PurchaseForm(frm_Stock);
then within the purchase form code...
public class PurchaseForm : Form
{
public PurchaseForm(StockForm frm_Stock)
{
frm_Stock.SomeControl.Text = "blah";
}
}
It is possible but not recommended way of doing it, you should have pass it to the other form via some shared object(i-e StateBag ). You can make the controls of Frm_Stock public and then they will be accsible from frm _Purchase when you make frm_Stock instance.
You should create a custom user control and use it on both forms.
If you want to share the same instance of the user control across the form, then create an instance when your application starts and add it manually on both forms when they load.
C# 3.5 Winforms...
So I’ve recently discovered the IExtenderProvider and how it can be used to extend controls with additional properties.
In a prototype project that I setup i put a break point on the ‘set’ method for my extendee property and as the form loads I could see the ‘set’ method executing for every control on the form; which is exactly what I wanted. Following the successful prototype I implemented the extender component into my main project. All the forms in my project inherit from a base form which I’ve added my extender component to. On the base form I set the modifier of the extender component to public so that its accessible by the form inheriting this base form.
Doing the same thing before i added a break point on the ‘set’ method for my extendee property but the method doesn’t execute for the controls in the form (but only for the controls in the base form). HELP!
I should probably add at this point that i’ve source controlled my forms and so most of them are checked-in (ie lock from modification). For the forms that I’ve checked out and modified the provider property; I’ve noticed in the designer file that all controls have an additional statement which calls the ‘set’ method of the provider property.
this.MyProvider1.SetMyProperty(this.txtTextBox1, false);
Am I right in thinking that for the extender component to work it has to physically modify the designer file or should it be able to cope with locked files and therefore call the set method dynamically? I guess if it does have to modify the designer file then this isn’t a problem for new forms or forms that get modified after the extender component was added to the project – but it would be problem when you have 101 forms all locked by source-safe...
I’d appreciate any thoughts...
At what point does the extender provider (IExtenderProvider) extend the 'type' (in my case a winforms control) that the extender was intended for; at design time or at run time?
The designer is responsible for showing you the properties of the extender in the property editor
Method bool CanExtend(object) from the IExtenderProvider interface
Am I right in thinking that for the extender component to work it has to physically modify the designer file or should it be able to cope with locked files and therefore call the set method dynamically?
It has to physically modify the designer file, and write the extended properties there
I guess if it does have to modify the designer file then this isn’t a problem for new forms or forms that get modified after the extender component was added to the project – but it would be problem when you have 101 forms all locked by source-safe...
This is is not a problem for new forms, and not for old forms.
If you want to set some extended properties, open the old form and set the extended properties (a check out of the file is necessary)
This really does confirm my suspicions, many thanks. But this does leave a problem in that the components are only extended if some physical change is made to the old form.
I was trying to hijack the Set property method to also add and remove an event handler to the component (if the component was a control). Image the property is a Boolean and when set to false it adds the event handle and therefore the default behaviour (setting to true doesn’t add and event handler)
To cut a long story short the controls which were part of newly added forms automatically have an event handler added even without me explicitly setting the property to false but the designer file of the old forms never modifier so the event handler wasn’t added.
As some background, I was trying to add a global event handler for all controls
Global event handler for all controls for User Help
The theme here is to add context help to my forms here’s example of the extender ( the event handler is added as part of the end initialiser)
public partial class HelpProvider : Component, IExtenderProvider, ISupportInitialize
... other code of the extender omitted ...
#region ISupportInitialize Members
public void BeginInit()
{
// do nothing
}
public void EndInit()
{
if (DesignMode)
return;
foreach (Component item in _disableOnlineHelp)
{
if (item == null)
continue;
if (GetDisableOnlineHelp(item)) // developer has decide to set property to TRUE
continue;
Control control = item as Control;
if (control != null)
continue;
control.HelpRequested += new HelpEventHandler(HelpProvider_HelpRequested);
_toolTip.SetToolTip(control, GetHelpText(control));
}
}
#endregion
#region DisableOnlineHelp Provider Property
public virtual bool GetDisableOnlineHelp(Component component)
{
object flag = _disableOnlineHelp[component];
if (flag == null)
return false;
return (bool)flag;
}
public virtual void SetDisableOnlineHelp(Component component, bool value)
{
_disableOnlineHelp[component] = value;
}
#endregion
One issue might be the foreach loop in the EndInit method:
Control control = item as Control;
if (control != null)
continue;
If the item is, in fact, a Control, you get out of the loop before executing this code:
control.HelpRequested += new HelpEventHandle(HelpProvider_HelpRequested);
_toolTip.SetToolTip(control, GetHelpText(control));
so you never add the Event Handler or the ToolTip, to any Control. Oops :)
Thanks,
John
Any thoughts,recommendations, patterns on a good way to manage an app with multiple forms.
First page is login, that loads a "main form", from there a user could launch a number of other "sub forms" (could grow over time). User should be able to cancel out of whole app at any point.
I know the way I do it right now is not always elegant.
Cody
Consider using the DockPanel Suite. It allows you to create multiple form, and have a complete docking panel solution for you application.
I like an Explorer-style interface: Use a splitter in the main form. Use a list control or tree control in the left side, and add a reference to each sub-form as a tag on an item. When the user clicks on the item, push the sub-form from the tag to the right side of the splitter.
You can monitor the select changed event on the list/tree to do form-level validation.
There's nothing fundamentally wrong with how you've set things up, but I would change the relationship between your login form and your main form so that your main form isn't loaded by your login form.
In the Main method in your Program.cs file, replace this (presumed) line:
Application.Run(new LoginForm());
with something like this:
LoginForm login = new LoginForm();
DialogResult result = login.ShowDialog();
login.Dispose();
if (result != DialogResult.Cancel)
{
Application.Run(new MainForm());
}
Rewrite your LoginForm so that it just returns DialogResult.OK if the login is successful (this.DialogResult = DialogResult.OK), instead of loading and showing an instance of MainForm.
From that point on, there's nothing wrong with loading and showing additional forms from MainForm, provided that a user interface like that makes sense for your program (like, for example, a graphics editing program that incorporates various other floating tool windows as needed).
The user can "cancel out" of your entire application by just closing the main form, which is quite normal behavior for a Windows program.
"to manage an app with multiple forms."
Hi Cody,
Tip : do keep in mind that you have access to a very handy way to know, at all times (in any context where you are using the System.Windows.Forms library) the number of open forms in the Application via :
Application.OpenForms.Count
I think a lot depends on what exactly you mean by "manage" your multiple forms, and by what you mean by the term "sub-forms." I'm assuming you're already familiar with the built-in MDI multiple window facility in .NET, and looking for an alternative to that, or you wouldn't be asking this question. Please correct me if my assumptions are wrong.
If you mean by "sub-forms" : forms created within the scope of your "Main Form," then they will, of course, be disposed when the Main Form is closed.
I personally like the "multiple independent window" model in WinForms sometimes referred to as SDI+ (I think it was Chris Sells that coined this acronym).
I like to start by "hi-jacking" the standard Program.cs file so the Main procedure looks like this :
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Initializer.Initialize();
// it's now your responsibility to shut down the application !
Application.Run();
}
Where 'Intializer is a public static class with one public static method 'Intialize; it might look something like this :
public static class Initializer
{
public static StartFormTemplate StartForm;
public static MainFormTemplate MainForm;
public static void Initialize()
{
MainForm = new MainFormTemplate();
MainForm.FormClosing += new FormClosingEventHandler(FormClosing);
// StartForm will display MainForm in this case
// MainForm.Show();
StartForm = new StartFormTemplate();
StartForm.FormClosing += new FormClosingEventHandler(FormClosing);
StartForm.Show();
}
}
Every form created within the scope of the Initializer class is going to be an "indepedent window" (effectively with : Parent == null).
The interesting "business" in this model is the logic in the FormClosing event (not shown here) which, in this example, both StartForm and MainForm share. You can easily test for the Mainform closing by taking the 'sender parameter of the FormClosing call and comparing to MainForm :
MainForm == sender
And you can use Application.OpenForms.Count to detect when there is only one "independent" window left to close. The tricky part is making sure you detect the cases where you want to keep the MainWindow open and handle those first, cancelling the FormClose event as necessary.
I think that's enough for starters : this may be a "primrose path" you don't really wish to go down :)
best, Bill
I would recommend the Smart Client UI Application Block.
The Block is designed to help you build complex, WinForm–based solutions. It provides a proven architecture and implementation that helps you to build applications using the common patterns found in line-of-business front-end applications.
It allows your application to be
based on the concept of modules or
plug-ins.
Maintainable, reusable code through UI composition.
It facilitates development using
patterns for loose coupling between
modules.
Separation of Model (business logic and data access) from Presentation.
The Model-View-Presenter pattern.
You can use MDI. To do this, set the IsMdiContainer property of the parent from to true, and set the MdiParent property of each child from to the parent from before the child form is shown. You can then use an MdiList menu to automatically list all of the child forms.
Alternatively, you can use tabs; this is easiest to do with a third-party framework.
Finally, you could do it normally by calling the Show method of each child form with the parent form as a parameter.
For a more detailed and specific answer, please provide more details.
I use a navigation-style UI for that sort of thing. Check out this article on MSDN which describes a WinForms framework for "inductive UI" applications.