In the WindowsForms what is the better way to initalize components:
in the properties window?
or in the code (in constructor)?
If I make it in the properties window, then I often have a situation, when I'm changing the value in the code and then closing the form. When I open it again, I'm getting old value (which I've written in properties) and it can confuse.
What is the differences between these two ways? Didn't found it in google.
It's equivalent.
When you change values using the properties window, that values are saved in the resx file. Then the method InitializeComponents(), that is written by the WinForms designed in the Form's constructor, performs the form initialization.
If you do it manually in the constructor, you must place your initialization code, after InitializeComponent() method, then, the form will be initialized with your values.
What method is better? In my opinion, both method are equivalent. You can choose the way you prefer. But my recommendation is not mix them. Use pure Winforms designer or pure code initialization.
Related
I've gone through multiple resources on trying to find the use cases of when to manually add code to InitializeComponent, but haven't found anything concrete. This suggests we shouldn't do it - The code within the method 'InitializeComponent' is generated by the designer and should not be manually modified
In the past, I had always used the form designer and never needed to manually make changes to InitializeComponent(). However at my new firm, the tech lead has completely ignored the form designer and manually added most UI elements within InitializeComponent (i.e. it has either been heavily edited, or completely re-written to the extent that the Designer can't recreate the GUI in VS, but the GUI is visible and fully functional at when the code is executed)
What is the advantage of not using the form designer? Is it just a matter of preference? Is manually editing/rewriting InitializeComponent for simple UI elements a good practice?
Thanks!
There are only a few reasons why one might need to edit InitializeComponent, such as:
To correct bugs introduced by a bad toolbox item designer.
To remove all traces of a control that cannot be deleted from the VS designer. (This has to be done carefully.)
To make quick "designer friendly" tweaks: changing a property value, adding a property setting, or removing a property setting. When adding a setting, I make sure it looks just like the designer-generated code.
After editing InitializeComponent, I always save & switch back to Designer mode to make sure I didn't break anything.
Any manual initialization code should be added outside InitializeComponent, e.g. OnLoaded() in a WinForms form or user control. As for fixing existing forms, it may be simple or nearly impossible depending on how complicated the form is, especially if controls have been added manually and required initialization methods (such as SuspendLayout, BeginInit) aren't being called.
I'm trying to implement Blackjack via Visual Studio, but have just been introduced to it. Suppose I have a PictureBox representing a card in a hand. This box starts with an image of a face-down card, representing a card slot that hasn't been dealt to yet. I have a function in my Form object that changes the PictureBox image to another card image resource based on an integer parameter. This is all pretty standard.
What I'm having trouble with is actually calling the method from main. I could create a new Form object and set the auto-generated one to invisible, but I'd rather work with the form that's auto-generated. Should I just put all the game logic in the Form1.cs file? Does the auto-generated form object have some default name I can use?
I realize this seems pretty novice level, but it seems like Microsoft's support documentation would prefer you create entire projects from the designer view and doesn't help much for actually coding.
The typical model for a simple Forms program is to allow the Main() method in Program.cs to remain in its default form: set some things up, create an instance of your primary Form subclass (the class name by default will be Form1), and pass that to the Application.Run() method.
It is good design to have a "controller" object outside of the UI object. But especially if you are starting out, you may well find it simpler and easier to understand if that "controller" logic is also in your primary Form subclass.
In that case, yes…all of the code winds up in the one .cs file, and indeed in the one object.
Even with the controller logic in the Form object, you will still find it useful to keep the code that is essentially controller logic separate from that which is user-interface logic, and to use the C# #region directive to label these sections of code. That will help you keep a mental model that still separates the two roles within the same class.
Beyond this, there are lots of differing opinions, from the complete "shoot-from-the-hip" approach, to the extremely strict and rigorous adherence to specific design patterns. But the above is consistent with the pattern that the Visual Designer leads you to, and so is a fine place for beginners to start.
I have a function that causes an exception in the designer. Can I avoid the call of the function if the designer loads it. Is there an attribute or something that is better than try catch?
Some more details:
I mean the visual studio designer for win forms. My form is using a signleton wich calls LoadProject() on initialize. Now I want to avoid that the designer calls the LoadProject() function.
Assuming this is WinForms - You can check if you are currently in DesignMode and just have your function return immediately.
There are some complexities that are fully explained in this article including a solution.
There are a few ways of detecting whether or not you are in design mode:
Check the value of the DesignMode property of the control. This does not work in a constructor of a control though, as it only returns true if the control has been sited, which does not happen until after the control has been created. It also has a bug whereby a custom control inside a custom control will always return false
Check whether the current application's path contains devenv.exe using Application.ExecutablePath.ToLower().IndexOf("devenv.exe"). If is does, the control is being instantiated by Visual Studio. A bit horrible, but it works.
Check LicenseManager.UsageMode for the value LicenseUsageMode.Designtime (have a look at my answer to Detecting design mode from a Control’s constructor for more details). Note that this does work in the constructor.
Wrapping the call to your function in any of these checks should solve your problem.
You might try looking at this article on the MSDN about using the DesignMode property. This might help you out. You can wrap your code that throws an exception in this in a conditional that avoids the code at design time.
Please note this will not work in the constructor, because the designer has to instantiate the object and then sets the property.
This is pure curiosity...
Most 'professionals' will likely never use "Form1" as a valid class name in their Windows Forms projects. I usually end up renaming it to MainForm.
What do you do?
Edit: For those of you that use hungarian notation (frmMain) - why? I don't think it would still be considered a standard practice... is it?
MainForm. I loathe Hungarian notation, and FxCop complains about it in any case, so MainForm, OkButton, AboutDialog, etc.
{AppName}Form.
frmMain is my typical choice.
Dennis. My form's name is Dennis.
frmMain for MDI applications. I don't bother changing it for single-form apps..
I prefer MainForm, not FormMain. Using Form as a prefix breaks alphabetical order!
I often use some variation of ApplicationShellForm.
This is because it's really, in most of my "real" work, nothing more than a thin shell where I inject the real behavior at runtime. My "main form" usually has very little in it, in and of itself.
That being said - I'd always call it something based on its behavior. What does your main form or application do? That's what would determine what I'd call it, if I wasn't building everything around dependency injection and trying to maintain some separation of concerns.
I usually name my main form to keep in line with the project. For instance, I'm (slowly) writing a small application that was intended to help manage peer reviews at my previous employer. My main form in this project was simply called ReviewManager.
Generally I rename it to frmMain, similar to statenjason. But if it has a different purpose, or is being used as a prototype that will get rolled into a larger project I will rename it to something more descriptive. So Form1 might become frmSomeComplexTest, or frmSomeMethodOutputTester.
I don't change it unless a different Form ends up being the main one. In which case, I'll rename that one Form1.
Form1, FormMain, it's essentially the same thing. It's not like your users will ever know/care, nor will it be confusing for someone maintaining your code.
If my program is named Fred, and its UI lives in a form, FredForm is what that form gets called. The moment there's more than one form, it gets promoted to FredMainForm, so long as it's actually still the centerpiece of the UI.
frmMain for single form apps, MDIMain for MDI apps. I name the project specific to the business purpose and let the business decide the form's text.
I've seen multiple posts and questions about the DesignMode property of Forms and UserControls. The idea is that you want to check if the control is in design mode (e.g. the control is shown in the Visual Studio Designer), and avoid code that can only be run in, well, run-time.
The problem I've seen many have - and my failing memory exposed me to it too, recently - is that the DesignMode property does not work in the constructor, and does not work for the nested controls.
However, it works extremely well in the Load event handler for your control or form!!
When you think about it, the code in the constructors of the Forms or UserControls should only deal with state that does not require the form to be loaded.
Code dealing with UI objects initialization should maybe be located in the Load event handler for the control. And in that function, the DesignMode property works. The Designer will use its proper value at that time.
In principle, the InitializeComponent() method has been called but in reality, when you show the control in Design view, the Designer only parses that function, it does not run it. The Designer, however, does run the constructor of nested controls.
If you absolutely need to put initialization code in the constructor, use theSystem.ComponentModel.LicenseManager class, it has a static property called UsageMode which takes values of DesignTime or RunTime. You can absolutely trust that property in the constructor of your control - but in the constructor only!
I had forgotten that little subtlety in the app I am working on at the moment. To get around the issue, I am adhering now to the pattern that all controls and forms which need extra initialization must implement a handler for the Load event. There, the DesignMode property works just fine, and I never have trouble opening my user control and forms in the Designer.
If I have a class hierarchy, I sometimes make that event handler virtual protected, and I only override it when the subclass needs extra initialization.
I am wondering, though, if there are better methods out there, or if there is something smelly about this pattern (other that having to implement a Load event handler many times?)
Because of the issues with using the DesignMode property with nested controls (and related problems), my general approach to this problem is to not even try to get my custom UserControls to function in design mode. Usually my controls are very complicated and owner-drawn, so even if the DesignMode worked with nested controls, it would take a great deal of programming effort to get them to show anything meaningful in design mode (and it would slow down development work, because the controls require a significant amount of initialization and setup time).
Usually I just add a public Setup() or LoadData() method that does all the work, and only call this method at runtime. In design mode, then, the UserControl just shows up as a square, which helps me position it and nothing more.
I'm interested in seeing if you get any other answers to this question, however, that might address your problems.