How to update Templates? - c#

Currently I'm creating a really big project in Visual Studio 2012, where there are some common settings for each form ("Cancel" and "Save" buttons, Methods that change in every form but have the same name, font sizes and types, form color etc.) it will save me a lot of time if I could do all the design a single windows form and when I edit or modify it, have the changes reflected in the other forms as well.
Let's say I need 10 forms, to create them I would choose this default format and have my menu and basic objects already placed and designed; then after 10 forms I decided to move a button a bit, but don't want to go to every form and move it; just change it in the original format, refresh and all my forms will have that button in the new location.
I used Templates as recommended by Can one set the default properties for new WinForms created in Visual Studio?. But I still have the issue that if I change something in the template it won't refresh in every other form created with the template to that point.
I've already thought of changing the InitializeComponent in the WinForm default format, but this is not recommended and I wouldn't want any errors from this later on.
Any ideas?
Thanks in advance

Inheritance will work for your solution.
Create "base" form with all "common" controls
Create new "derived" form and change form to inherit from your "base" form.
If you have some common logic in base form, which need to be "overridden" in derived forms - put it to the virtual method
// Base form
protected virtual void Close()
{
// Base logic
}
private void CloseButton_Click(object sender, EventArgs e)
{
Close();
}
// In derived form - just override "Close" method
protected override void Close()
{
// custom logic - will be executed when "Close" button clicked
}
In base form leave empty space for custom controls. Because you will not be able access baseform controls through designer in derived form.
Another approach - Model-View-ViewModel(MVVM)
- Introduce own UserControl with common controls(view) which have property - instance of ViewModel.(Viewmodel will contains behaviour logic and possibility to change "base" settings.)
- Add this user control to all "derived" forms and set UserControl.ViewModelProperty to instance which will represent logic for this particular form.
Without knowing "full" context of your goals - difficult to suggest more, but I am pretty sure you can build maintainable relations between forms, which can share common logic and view.

No, there is nothing you can do. Once you use a template to create a project or a file, it becomes a one-off. You have to edit it manually, or use a text editor that is powerful enough to employ a find and replace with pattern matching and capture group insertion.

Related

"Include" instead of ShowDialog()

I'm trying to make a WindowsFormApplication in Visual Studio 2015 and need some help.
I've been trying to search for the answer on internet but can find out how to do the following:
I have two windows (solutions?). I open the second window with a button in the first one with this code:
this.Hide();
intermec prodinter = new intermec();
prodinter.ShowDialog();
My question is:
How can i "include" the second window (like "include" in PHP) instead of close the first window and then open the next one, like it does now?
A Form is just another Control. Think of it as a Container (because it holds other Controls).
A User Control can also hold more than one Control. There are ways you can display a Window inside another Window in a WinForms app, but the desired effect is not always guaranteed. So it would be best to place all of your controls (for "page 1", for example) in a User Control called "Page1", and then, when appropriate, add that User Control to the Form, and set its Dock property to Fill.
And when it's time to show a different "page", Hide(); "Page1", and Show(); "Page2".
I think you are talking about form inheritance:
Just create a form, lets call it as frmBase. And add some controls onto frmBase which you want to have on other forms as well.
Create other form, lets call it as frmDerived.
In the code behind of frmDerived, just do the following:
// derive the frmDerived form from frmBase
public partial class frmDerived : frmBase
{
public frmDerived()
{
InitializeComponent();
}
}
And then just check the frmDerived form design, it should include everything from frmBase.
And you may want to make the access modifier of some controls of frmBase to Public as required to access them on frmDerived.
I hope this will help you. :)

What is the most efficient way to create a Win form with multiple pages?

My goal
I am working on a project in C# using Visual Studio 2013. The project is one that I intend to contain a lot of pages. These pages are all linked together using buttons. My problem is that I cannot come up with an efficient and elegant solution for this.
My attempts
So far I have came up with two potenial solutions to my problem. First I added extra forms and then on button press I hid the current form and displayed the new form, like so:
Form2 frm = new Form2();
frm.Show();`
Form1.Hide();
While this does work, I have two problems with it.
My project will end up with hundreds of forms
The transition between forms looks sloppy. I am aiming for a browser like transition by where all navigation occurs on one window, without opening and closing others.
The second potential solution I tried incorporated the use of Panels. So I essentially created each page on a different Panel. Then the appropriate panel was shown upon a button press and the rest were hidden. Like this:
private void button1_Click(object sender, EventArgs e)
{
mainMenuPanel.Hide();
submenuPanel1.Show();
submenuPanel2.Hide();
submenuPanel3.Hide();
submenuPanel4.Hide();
}
This is exactly what I was looking for however my issue with it is that managing the vast amount of panels quickly became a nightmare. Editing the controls on a Panel that was hidden behind 9 other Panels and as the number of panels in my project was only going to grow - this does not seem like the ideal solution in its current form.
In my head I thought there maybe an option in Visual Studio 2013 that allows me to 'hide' the Panels I am not using on the form, or drag them off the form temporarily. Is that an option in Visual Studio.
If not do any of you know a more efficient and manageable way of achieving this?
Thanks in advance.
If you are stuck using WinForms, your best bet is probably using UserControls. you can actually extend the UserControl class out to be a "page" ie: UserControlPage. This makes the form much simpler in function, but you will need to do some finicky work with handling events /passing data if the controls need to talk to each other.
if you aren't nailed into using Winforms, WPF supports all of this natively, and has wonderful tools for building all the pages you would need, and storing/populating your data, and propagating events.
If you want to have single form with changing content, and you don't want to mess up with panels in one form, then solution is user controls. You will be able to create them dynamically and add to form controls. Also there is no mess, because your form will be very simple - you can have single 'placeholder' control which will be used to dock user control which is currently displayed (e.g. panel control):
private void ShowContent(Control content)
{
placeHolderPanel.Controls.Clear(); // clear current content
placeHolderPanel.Controls.Add(content); // add new
content.Dock = DockStyle.Fill; // fill placeholder area
}
Usage:
private void button1_Click(object sender, EventArgs e)
{
ShowContent(new FooUserControl());
}
You could subclass the Panel class and create as many of those custom panels as needed, then they would be inserted on your Main Form, and managed as you described.
The advantage is that you would be able to individually edit them as a separate user control.
The drawback is that you lose direct event handling of controls on those panels from the main form. You can still define your own events on those panels and delegate the individual control events.
There's always a trade-off somewhere.
Cheers

.NET (non-visual) component

I need to create a non-visual component, FooComponent, that will do some management for all controls of type Bar that resides in its form.
I have the following constraints:
The FooComponent can only be added to forms.
Only one FooComponent per form is allowed.
FooComponent should register to the form closing event, and when it fires and to some function on all Bar's and sent the e.Cancel value based on the returned values.
#1 and #2 above should be enforced on run-time as well as design time.
#3 event registration should be made automatically and not by the FooComponent's users.
I searched Google and MSDN for some help and read about Component and ComponentDesigner classes, but I didn't find anything for the rescue.
What should I do?
(1) To control that the component can only be added to a form, use a FooComponent constructor that is passed a form, and don't define the default constructor. It's called like:
FooComponent component = new FooComponent(this);
where the component is created from within the form itself. By not-defining the default constructor, this:
FooComponent component = new FooComponent();
will not compile.
(2) Expose a FooComponent property on the form itself, and in the constructor of the FooComponent, set the passed form's FooComponent to this.
(3) Same thing, in the constructor for the FooComponent, register with the closing event for the form you passed
Put it all together and you get:
public class MyForm : Form {
public FooComponent OwnedComponent { get; set; }
}
public class FooComponent {
public FooComponent (MyForm OwnerForm) {
OwnerForm.OwnedComponent = this;
OwnerForm.FormClosing += MyCallback;
}
private void MyCallback(object sender, FormClosingEventArgs e) {
...
}
}
EDIT
Unfortunately, if you need the default constructor, and if it has to be a true drop-on-the-form Component, there's no way to enforce that a component is only created on a Form, or that the Form only has one instance of the component (not from within the component, anyway).
The problem is twofold:
(1) Dropping a component doesn't add the component to the form, it adds it to the form's components collection. So even if you could get a handle to the parent/owner, it will never be a form.
(2) As Neil pointed out, dropping a component onto a form calls the default constructor, which passes no parameters, and, of course, none of the component's properties (such as site or container) are populated.
Possibly helpful: A component can be designed to be notified when it is created in a couple of ways:
(1) By implementing a constructor that takes an IContainer parameter. When the component is dropped on a form, the generated code will call this constructor, instead. However, it will only do this at runtime, not design time. But the container will be a handle to the form's components collection.
public FooComponent(IContainer container) {...}
(2) By implementing ISupportInitialize. When the component is dropped on a form, the generated code will additionally call BeginInit() and EndInit(). In EndInit(), you can access properties such as the Site and Container. Again, you'll only get this at runtime, not designtime, and throwing an exception here won't stop the component from being created.
Old, but excellent articles on Components and Controls from MSDN Magazine by Michael Weinhardt and Chris Sells.
April 2003 Building Windows Forms Controls and Components with Rich Design-Time Features
May 2003 Building Windows Forms Controls and Components with Rich Design-Time Features, Part 2
These are now .chm help files. You will need to unblock in the file's property page to enable reading the contents after downloading.
I don't think it's possible to define exactly what a contained class can be contained within. I've certainly never seen an instance where I've gotten an error (or even a warning) for setting up a property of one type in another, even in WinForms.
Something you might be able to do is to define a Form-derived ancestor for your forms that contains a reference to your (internally-visible) FooComponent, initializes one on instantiation, and attaches the handlers. For best results it should be parameterless and the only constructor overload, so it forms the base for any constructor your consumers come up with. Then, just make it a house rule that forms derive from your ancestor class and not directly from Form (you might be able to use a code inspection tool like FxCop or similar to enforce this when code is committed to source control). Your users now get a FooComponent in every Form they create, cannot create their own (it's internal and should be in another project with your Form ancestor) and don't have to do anything other than derive from the new class to make their forms behave the way you want.
You are asking for a lot. In general, making components aware of the form they are dropped on is quite difficult. This answer can help you get the event handler implemented. You'll need to implement ISupportInitialize to get the EndInit() call to setup the event handler.
Preventing multiples is quite hard too, I can only think of a custom designer that can step in early enough to prevent the 2nd one from being added.

Calling Methods from seperate usercontrols in the same form

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.

How can I easily keep consistent UI settings in C# Winform application?

I have a lot of different UserControls and would like to maintain consistent UI settings (mainly colors and fonts). My first try was this:
public class UISettings
{
//...
public void SetupUserControl(ref UserControl ctrl)
{
ctrl.BackColor = this.BackColor;
}
}
to be called in every control like this:
settings.SetupUserControl(ref this);
As this is read-only it cannot be passed by ref argument so this does not work. What are other options to keep consistent UI without manually changing properties for every item?
Inheritance! If you have a form or control that will constantly be using the same styles and you want to set that as your base, just create your own user controls that inherit from a form/control. By default all of your forms will inherit from "Form". Instead of inheriting from the default form, create a new user control that inherits from Form, and then have that as your base class.
CustomForm : Form // Your custom form.
Form1 : CustomForm // Inherit from it.
...the same works for components. If you want a button to have the same styles across the board, create a user control and have it inherit from the button control -- then use the custom control.
Whenever you want to make a change to your base styles, or any settings, simply change your custom controls settings -- your new forms/controls will automatically be updated!
Do the same thing. Don't pass it by ref. UserControl is a reference object already, so there's no need to pass it into your method using the ref keyword.
You may also want to consider a recursive method that will find all the UserControls on the form and pass it into your method.
How about a base class which provides such settings?
Two answers:
You don't need ref, controls are objects are reference types. Just drop it.
Create a Base UserControl and derive your controls form that base. You can still do that, just edit the class definitions of the controls. For new controls you can follow the Wizard.
A tip: setup the styling in the baseControl. Then make sure the derived controls don't override, the best way to do that is scanning the *.Designer.cs files and remove all settings that you know should come from the base.

Categories

Resources