Using DesignMode property vs. LicenseManager.UsageMode - c#

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.

Related

How to use SynchronizingObject for event calls

For an application that I'm working on I use SpotifyLocalAPI, and I want to use the events that the API has. But, as someone who is into C# for a couple of months now, I'm not sure where to start. There is another project based on this API that uses the events, but it's in WPF, and that makes it a different deal if I understand my googeling correctly. This means that for a WinForms I have to do things a bit differently, but I can't seem to figure out how.
The documentation of the API states that You can set a SynchronizingObject, then the events will be called on the specific context. When I look at how the WPF project did this, it has a function (found here) to do some magic, and poof, it works.
If I understand this answer correctly the SynchronizingObject is a property of the ISynchronizeInvoke interface, which "provides synchronous and asynchronous communication between objects about the occurrence of an event.".
Okay, so far so good. I think I understand the basic working of the interface, but how am I supposed to work with it? How do I convince the application that it should react to the event? How should I define the _spotify.SynchronizingObject? (Which is the main problem for me right now)
You can set the SynchronizationObject to be any UI element that implements IShynchronizeInvoke (Form, UserControl etc). Check out the example Winforms app here. Note that this is optional, and in that example app, they have chosen to use Invoke() explicitly in the event handlers. The important thing to remember is that if you want to update the UI, then the code to do so must be run on the UI thread. Some more details on this here.

Editing the InitializeComponent() method C#

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.

Initializing components in the WindowsForms

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.

(nested) user controls within a mvp pattern causing sporadic problems

I have a serious problem with nested user controls (UCs) in WinForms while trying to implement the mvp pattern (passive view). The project consists of one model (designed as a singleton) and a set of different presenters with corresponding view interfaces. To avoid one huge view interface and therefore an overloaded main UI, I decided to make use of a set of different UCs. Each UC has one view interface and one presenter that can access the model. But there are nested UCs: meaning that one specialised UC implements sort of a basic UC. The main UI just represents a container for all those UCs. So far, so good (if not, please ask)?!
There are two problems that I am facing now (but I guess both are of the same origin):
From time to time it is not possible anymore to load the UCs and test them within the Visual Studio 2008 User Control Test Container. The error message just says that a project with an output type of class library cannot be started directly etc. I can "handle" that by unloading all UC projects and reloading them afterwards. (I guess the references to all mvp components and other UCs are then updated).
Assuming that the implementation of my mvp pattern is okay and all those UCs are testable within the VS Test Container at a certain time - there is the biggest problem still left: I am not able to add any UC (even the basic and unnested ones) to a simple Form (UI).
Could it be that my basic UC causes all these Problems?! It consists of two simple ComboBoxes and implements a basic presenter and basic view interface. Whenever I add this UC to a different UC the VS designer adds two references to the public getter methods of the UC as resources. I then manually remove those resources from the resx-file and commend the corresponding lines in the designer file.
For the second one: You should use DesingMode property of the Component class (which UserControl derives) in your code. Be aware, there is a bug with this property not having correct value with nested user controls.
This can help you, I think: When your WinForms UserControl drives you nuts

c# Hide function from Designer

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.

Categories