Add generics to form - c#

When I add a generic type to a form in C# I get errors like
InitializeComponent does not exist in the current context
and the same for all of my components.
Here is the code:
public partial class Form1<T> : Form
{
public Form1()
{
InitializeComponent();
}
}

First and foremost, Form1 is a partial class, it exists in more than one file.
Since you changed the Form1.cs file to have a generic Form1<T>, you also need to change the corresponding Form1.Designer.cs file to have a generic class.
Otherwise the C# compiler looks upon the two files as containing two distinct classes, one Form1<T> and one Form1. While they technically have the same name, they're distinct. You can declare a generic and a non-generic type with the same name at the same time.
So change both files.
Now, having said that, you cannot have generic forms. When you succeed in getting the compiler to compile the code (with the above described change) you will find that the form designer in Visual Studio is no longer happy with you and is unable to visually design the form.
As mentioned in the comments to this answer, if you can live without the form designer then this won't be a showstopper.
However, if you cannot live without the visual form designer then this cannot be fixed, other than to remove the generic parameters to Form1 that you added in the first place.
So you should try to find a different way to do what you want.

InitializeComponent() is a method that Visual studio generates automatically for the forms created using visual designer. This method is located in your_form_name.Designer.cs class that is "visual" part of your form where controls placed on form defined.
Probably you've just copy-pasted it from another form created in such a way. If your custom class doesn't has "visual" part like Form1.Designer.cs class in your solution - then just delete this method call from constructor. Otherwise make sure your "visual" class part has this method.

Related

How to inherit a form from a class library (on a separate solution)?

I have a custom form from Solution1
public partial class MasterForm : Form
{
public MasterForm()
{
InitializeComponent();
}
}
however, upon creating a new solution (Solution2), trying to inherit the MasterForm (from Solution1).
I don't see the MasterForm in the Inheritance Picker (Unless I browse for the .dll).
Update:
From what I understand is, the two solutions are referenced, like if Soln 1 is using the class from Soln 2, Soln 2 has to be added as a reference to Soln 1.
Once it is done, the namespace of the class for Soln 2 has to be used (usually the Visual Studio IDE will give the suggestion for the reference issue if you are using it).
But this should solve the issue.
I have reproduced your problem. It seems that I can do nothing for Inheritance Picker.
However, I suggest that you can write a small code to inherit the form.
Code:
public partial class Form1 :Inheritance.MasterForm
You can change form to Inheritance.MasterForm to do it.
Finally, you can look at the form from the dll.

Namespace problems between custom/user controls

I have a project I've been working on for quite a while, and I've run into a referencing problem. Currently the solution outline looks like this:
Solution
Agent_Toolbox namespace
MainWindow
CallTemplate (UserControl)
CallTemplate class
CustomTextBoxes namespace
NumberTextBox (CustomControl)
NumberTextBox class
My problem is that CallTemplate uses one of the NumberTextBox custom controls. I need to reference the CallTemplate class from within the NumberTextBox class in a typeof statement. ie:
ParentControls parentControl = new ParentControls();
Visual parent = parentControl.GetParentControls(this, 3);
if (parent == typeof(CallTemplate))
{
//Do something
}
But no matter what I try I can't get VS to recognize CallTemplate in this instance as a class. I tried adding a reference to NumberTextBox, but it gives me an error of circular redundancy. I also tried seperating CallTemplate into a separate namespace, but then it can't find NumberTextBox without a circular redundancy. Ont thing I thought of doing was placing all the User/Custom controls into a separate project within the solution, but then the xaml couldn't find CustomTextBoxes in order to add the box into the CallTemplate. I'm prertty much frustrated and at a loss, and convinced it's something simple I'm missing.
Any ideas please?
Edit:
I added a UserControl to the CustomTextBoxes project. VS studio placed it within the same namespace, and generated
public partial class CallTemplate: UserContol
{
public CallTemplate()
{
InitializaComponent();
}
}
If I try to rename the namespace it renames the whole namespace, rather than just this file's. So I created a new namespace underneath, and pasted the CallTemplate code within it. VS balked at the InitializeComponent() method, saying it doesn't exist with in the current context. Basically I need to know how to migrate one part of a namespace's code to a different namespace.
Two projects cannot reference each other. If they did, how would visual studio know which to build first? When that happens, it usually means it's a design flaw. Combine your projects, or have the references only go one way.

Creating partial class in C#

I am a student and I dont know what a partial class is. The following code belongs to a partial class
I automatically created the partial class:
public partial class EGUI: Form
{
private OleDbConnection dbConn; // Connectionn object
private OleDbCommand dbCmd; // Command object
private OleDbDataReader dbReader; // Data Reader object
private Emp Edetails;
private string sConnection;
private string sql;
}
Here is the definitive answer: http://msdn.microsoft.com/en-us/library/wa80x488(v=vs.80).aspx
It is possible to split the definition
of a class or a struct, or an
interface over two or more source
files. Each source file contains a
section of the class definition, and
all parts are combined when the
application is compiled.
First of all, THIS: http://msdn.microsoft.com/en-us/library/wa80x488(v=vs.80).aspx
Second of all, it allows a way for a programmer to collect specific pieces of code into two different files. A really good example of this is when creating an ASP.NET WebForm. The WebForm will have a file for your event handlers and such (Button_Click etc) and then you will have an extra file that contains the declarations of the ASP.NET controls you are using on your page. This keeps the code you CARE about in one file and the more obvious 'auto-generated' stuff in another.
Correct me if I'm wrong, but I also believe partial classes may allow you to do something similar to 'monkey patching' because it exposes the class in such a way that you can add new methods, variables etc and have access to the classes private members.
A partial class is a class whose definition could be split among different files inside the same project/assembly. For example Visual Studio Forms Designer uses this functionality extensively in order to split the design time controls that you have placed on the form from the actual code, and once the project is compiled the two source files are merged to emit the resulting class.
Check this out. There is a simple example for beginners on partial classes and partial methods.
http://w3mentor.com/learn/asp-dot-net-c-sharp/object-oriented-concepts-c-sharp/partial-class-and-partial-method-in-c/

Adding Interfaces to DataContext Classes

I am using Linq-To-SQL and I would like to attach an interface to each of my entities.
I can edit the designer.cs file and accomplish this.
However, when I make a changes to the dbml through the UI it rewrites the whole designer.cs and I lose my changes.
Am I just going to have to deal with it, or is there a way to get around it?
I am doing this in the designer.cs file(the IMatchable is a custom interface of mine):
public partial class Error : INotifyPropertyChanging, INotifyPropertyChanged, IMatchable
{
...
}
Don't edit the designer file; the beauty of partial classes is that you can create a separate file with just
public partial class Error : IMatchable
{ }
(assuming that we are using implicit interface implementaion by virtue of having properties that match the required interface)
Small word of caution though: if you are using VS2008 and you have MyClasses.dbml and MyClasses.designer.cs, do not call this file MyClasses.cs - there is a bug in VS2008 that makes this a nuisance (you have to keep moving the using directives inside the namespace, or the code-generator breaks) - fixed in VS2010 though.
Also, if it was a single interface, that every type in your model implemented, you can cheat by specifying that at the object base-type in the DBML. The designer doesn't show this option, but if you edit the DBML manually it works fine.

Fix embedded resources for a generic UserControl

During a refactoring, I added a generic type parameter to MyControl, a class derived from UserControl. So my class is now MyControl<T>.
Now I get an error at runtime stating that the embedded resource file MyControl`1.resources cannot be found. A quick look with .NET Reflector shows that the resource file is actually called MyControl.resources, without the `1.
At the start of the MyControl<T>.InitializeComponent method there is this line which is probably the one causing problems:
System.ComponentModel.ComponentResourceManager resources =
new System.ComponentModel.ComponentResourceManager(
typeof(MyControl<>));
How do I force the ComponentResourceManager to use the embedded resource file MyControl.resources? Other ways to resolve this issue are also welcome.
Turns out you can override the resource filename to load by inheriting from ComponentResourceManager like this:
using System;
using System.ComponentModel;
internal class CustomComponentResourceManager : ComponentResourceManager
{
public CustomComponentResourceManager(Type type, string resourceName)
: base(type)
{
this.BaseNameField = resourceName;
}
}
Now I can make sure that the resource manager loads MyControl.resources like this:
System.ComponentModel.ComponentResourceManager resources =
new CustomComponentResourceManager(typeof(MyControl<>), "MyControl");
This seems to work.
edit: the above line is overwritten if you use the designer, because it is in the
generated code region. I avoid the designer and make use of version control tools to revert any unwanted changes, but the solution is not ideal.
In addition to Wim's technique, you can also declare a non-generic base control that has the same name as your generic class, and have your generic control/form derive from that non-generic base class.
This way you can trick both the designer and the compiler into using the resource file from your generic class, and you get permanent designer support once the base class is setup without having to fiddle in the .designer file everytime you rebuild :
// Empty stub class, must be in a different file (added as a new class, not UserControl
// or Form template)
public class MyControl : UserControl
{
}
// Generic class
public class MyControl<T> : MyControl
{
// ...
}
The only requirements are to have exactly the same name for your generic class and its base class, and that the base class must be in another class file, otherwise the designer complains about not finding one of the two classes.
PS. I tested this with forms, but it should work the same with controls.
On my Visual Studio 2008 I have this error:
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MyControl));
Using the generic type 'WindowsFormsApplication1.UserControl1' requires '1' type arguments.
Notice that in my case code was generated without parentheses, <>, after the class name.
It is becoming interesting, see ImageList autogenerates non-compiling code in a Generic User Control.
What they said:
Posted by Microsoft on 7/6/2005 at 2:49 PM
This is an interesting bug. You've hit upon a generic scneario that we do not support in the Windows Forms designer. We will not be able to add support for this in the Whidbey (my note: Visual Studio 2008?) release. We will consider this for a future version. As a workaround, you can use the designer to create a none generic UserControl with a public Type property and then create a generic class that inherits from it and passes T into the base classes Type property.
I suppose this control cannot be designed in the Visual Studio forms designer either.
The simplest and easiest workaround is to make a dummy class for the autogenerated typeof(). You do not need to inherit from it or even expose it to the outside:
// Non-generic name so that autogenerated resource loading code is happy
internal sealed class GridEditorForm
{
}
(In my experience, the time required getting the designer to work around generics was not worth the ideal coolness generics can provide. I won't be using generic windows forms or controls again.)

Categories