c# windows forms create generic form [duplicate] - c#

I'm using vb.net (vs2010). I'm moving some winforms to a dll. I have a form that inherits from the one which has some subs and functions (like a test app).
My original form is: (.designer)
Partial Class Form1(Of T)
Inherits System.Windows.Forms.Form
....
End Class
Form itself contains code and a toolbar.
My test form is: (.designer)
Partial Class TestForm
Inherits Form1(Of Class1)
I get "Cannot create an instance of Form1`1[T] because Type.ContainsGenericParameters is true" when VS try to load the designer. App is usable. I can build and run the project without errors, but I need to add controls and some code to each new form.
I tried many ways:
Visual Studio 2008 Winform designer fails to load Form which inherits from generic class
How can I get Visual Studio 2008 Windows Forms designer to render a Form that implements an abstract base class?
http://www.codeproject.com/Questions/419770/Csharp-reflection-GetValue-from-a-field-in-generic
http://madprops.org/blog/Designing-Generic-Forms/
All examples are for C#, and I don't know if I'm missing something...
Is this a bad design ? I know this is a VS bug but still it seems everyone fixed it by these links.
EDIT:
I'm building a DLL. Form1 is on this DLL and TestForm is in a new project. Those links works if I'm in the same project (a.k.a. the dll).
Thanks!

Is this a bad design ? I know this is a VS bug
Bad design, not a VS bug. What you are trying to do is fundamentally incompatible with the way the Winforms designer works. It has strong WYSIWYG support, the designer creates an instance of the form's base class and allows code in that base class to run at design time. Which is why, for example, you can set the BackgroundImage property and it is immediately visible in the designer. The Form.OnPaintBackground() method paints it. The designer is not involved at all, it just sets the property.
To make that work, it must be able to create the base class object. It can't in your code, it doesn't know what kind of T to use. Not an issue when you design Form1, the T isn't needed yet since it derives from Form and creating an instance of Form is not a problem. Big issue when you design TestForm.
You'd probably argue that it should use Class1 as the T. It doesn't, the odds that it can use Reflection to discover the generic type argument from TestForm are exceedingly low. That requires the type to be compiled first. That's a chicken-and-egg problem at design time, the TestForm class gets compiled after you design it, not before or while you design.
It's not like you completely cannot use your approach. It builds and runs just fine. You just have to live without design time support for TestForm. That's usually a deal breaker, you have to re-consider your design.

Related

C# custom Windows Forms base class and designer

I am trying to implement the GUI part of a plug-in, which means that I have to inherit from a custom base class (which inherits from UserControl) included with the plugin assembly.
When implementing my own control, I would normally inherit from UserControl and going to the designer would be really straightforward (just double clicking on the solution explorer).
In order to be able to work with the designer, I do a first implementation using UserControl as base class.
The problem is that as soon as I change the base class into ApplicantTabControlPlugin (the custom base class provided by the plugin), I cannot open the designer for this control anymore. I.e., if I close the designer, it seems it is gone forever.
Is there any way to prevent this behaviour?
You should add
<SubType>Component</SubType>
to the project file entry of your base class.

A partial class has multiple form

When I write a winforms application, I tend to create an Implementation.cs file for each form.
Say I have Form1.cs, I'd create a new file called Form1.Implementation.cs starting with partial class Form1.
Form1.cs just contains all the event callback methods (what the designer has done), everything else goes to Form1.Implementation.cs. It helps me write more readable code.
I wanted Form1.Implementation.cs to be a "subfile" just like Form1.Designer.cs is, so I edited .csproj file.
<Compile Include="Form1.Implementation.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
After reload, however, Visual Studio automatically adds <SubType>Form</SubType> right after DependentUpon element. Doubleclicking Form1.Implementation.cs doesn't show code but a designer with another initial empty form.
It's like
"class Form1, which ISA Form, is(?) multiple forms."
I tried adding DesignerCategory attribute to class Form1, but it affects Form1.cs, as well.
Well, hitting 'Shift-F7' or 'Ctrl-Shift-0' is not a big deal.
I wonder if...
it's a glitch of Visual Studio,
the secondary(?) form really exists somehow,
it's going to blow up my winforms project someday
The only way of achieving what you tried is by adding <DependentUpon>, which you already know. Now Visual Studio automatically adds the <SubType>Form</SubType> for any class derived from Form. Since your Form1.cs probably contains the line public partial class Form1 : Form, this is where the SubType is coming from.
The other files - Form1.Designer.cs and Form1.Implementation.cs may contain only partial class Form1, but since partial class definitions across multiple files are still effectively one class definition, Visual Studio detects that it still inherits Form. I believe you may already know that, but just in case here's the MSDN article about the partial keyword. Don't worry about there being multiple instances of Form in this scenario. Remember this still is just one class - Form1, no mater over how many files you spread it.
In the end, all code files containing classes (even partial!) inheriting Form (or UserControl) are automatically opened in the Designer. This behaviour is by design.
The solution here is simple - either make a code file defining a separate class not based on Form, or just use F7 to view the code of that file in Solution Explorer, however annoying that may seem. It doesn't matter if that code file is <DependentUpon> anything or not. Only the inheritance of Form or UserControl matters.
The best solution though, in my opinion, would be to stick to what Visual Studio is giving you:
Designer-generated code stays in Form1.Designer.cs
Your code (what you put in Implementation), goes in Form1.cs (hit F7 to view that code instead of going to the designer)
This is an approach my team has been sticking to for a few years now. It provides a basic means of separation of Designer code and hand-coded actions. To better separate your code, use a design pattern such as MVP, as suggested by Simon Whitehead in the comments.

*.Designer.cs file is missing

I'm using Visual Studio 2010 and when I create a form, I get a FormName.Designer.cs file with all the auto generated code.
This is exactly what I want, however, when I do the following:
Created an empty class.
Subclass System.Windows.Forms.Control
Add a System.Windows.Forms.ImageList to the designer.
Add images to the ImageList in the designer.
All of the auto generated code gets dropped in my class file and I don't get a *.Designer.cs file.
How do I get VS to always use a *.Designer.cs file?
Update
Declaring a class partial and subclassing UserControl is not sufficient. I had to select "UserControl" when I created a new Item, then I got a designer.cs file.
This is normal and the way the designer worked in versions of Visual Studio before VS2005, versions that did not yet support partial classes. You only get the separate Designer.cs file for a class that's derived from Form or UserControl and you declared them with the partial keyword.
Not 100% sure what's the underlying reason, but surely it has something to do with the very simple designer for the Control class. The designers for Form and UserControl are much fancier.
Nothing actually goes wrong so this is not a real problem. There is very little bang for the buck, especially since it is so uncommon to actually need another component or control when you create a custom control. Getting the Properties window to work is a convenience but, in my personal experience, isn't worth the considerable annoyance of getting the designer page by default when you double-click the class in the Solution Explorer window. I lost count of the number of times I shouted "crud!" at the machine.

C++ Parenting a WPF window from another assembly and handling events

I've been unable to make this work because of what I believe is a glitch in Visual Studio, so I'd really appreciate if someone could attempt this situation and share what happens.
I have setup in a solution 2 projects:
- a C++ application which has been CLI enabled (.exe)
- a C#/WPF class library which has a .xaml form inside with a matching .cs window class (.dll)
I want to spawn the WPF window inside my C++ application, so I import its reference and create a new instance of the window and run under a new application context. Thats works fine.
I now want to make classes out of this window and handle different events inherited from protected functions in the C# window, so In the C++ assembly make a public ref class whom child is the .cs class of the .xaml powered window. This compiles fine.
ie:
public ref class myCPPWindow : myWPFWindow { ... };
I then change the window I spawn to the parent class which is located in the C++ assembly rather than the base class located in the C# assembly. Now I get an error on the InitializeComponent() part of the base C# class while loading the .xaml window that I require saying that it fails to load the .xaml window source from the C# assembly even though the base class works. Can anyone give an explanation/fix for this?
It looks like a common [library;user control]-[application;derived control] issue in WPF - I reproduced that even without C++. Without digging into explanation, general workaround is either aggregating "base" class or re-degisning base class to be templated control instead of user control (e.g. without .xaml file). If I understand correctly, your question is the same as The component does not have a resource identified by the uri question.

Why does my class suddenly have a 'designer'?

I just finished adding and removing different database models (I was trying to figure out which one I should be using for this project) then after playing around for a while I noticed one of my classes's icon changed from what is shows beside my Calculations.cs class in the first image to the Balance.cs icon.
The Balance.cs now has this Designer component so when I double click on it I see my second screen shot. This seems to be allowing me to add components from the toolbox to my class. There are actually two classes within my Balance.cs. This Designer thing is only affecting/interacting with one of them (it inherits from SerialPort).
I don't really know what changed or what I did to make this happen and ctrl+z is not being my friend here. How do I change Balance.cs back to a regular class with no designer component?
Thanks
If any of the classes in a source file inherit - either directly or indirectly - from System.ComponentModel.Component (such as SerialPort), Visual Studio will provide design-time support to you. This is sometimes unwanted behaviour, and you can safely ignore it in most cases.
If it really bothers you, you can decorate your class with the [DesignerCategory] attribute (set the category to an empty string).

Categories

Resources