Non visual inheritance of WinForms with vb.net - vb.net

I have two Forms, which have similar Functionality (i.e. an amount of similar Controls) but complete different Layout. So the normal inheritedForm (which VS2010 provides) wont work here.
I have tried following:
Public Class BaseForm
Inherits System.Windows.Forms.Form
Friend WithEvents Button1 As System.Windows.Forms.Button
End Class
And in Form1.Designer.vb:
Partial Class Form1
Inherits BaseForm
...
<all Designer generated Code>
...
' Friend WithEvents Button1 As System.Windows.Forms.Button <- remove this Line
End Class
If i compile/execute this, the test form works as expected; But now I am unable to design the form any longer.
If I switch to Design-Mode, it says:
The variable 'Button1' is either undeclared or was never assigned.
So it looks like, the Designer only tries to guess how the Form looks like by inspecting the top-most Class, without compiling the full inheritance-Tree...
Does anyone know a workaround for this?
Thx,
Daniel

I have a feeling you have some existing controls on the base form which you want to bring to the inherited form and then add more functionality of your own. Remember one thing, inheritance in VB.NET is by default set to shadowing, so you can redefine code in your inherited page for the same button to do a different function.
However, I think you forgot the Overridable keyword when declaring the form elements in the parent form. This will help the compiler know that the form can be overridden and allow you to define custom functionality.
Remember, all controls and pages in VB.NET are classes and whatever we learned during OOP classes in college apply here.

Related

How to make existing forms deriven from a base form in VB.net

I have an existing project in VB.net with many Windows forms.I want to change all forms to deriven from a base form created in a class library.
is there any way to do so?
if i do inheritance with a code like this the designer dose not show the child form and gets error
Class Form1
Inherits BaseFormLibrary.BaseForm
Since you want to change existing forms to inherit another base class you need to change each form that you want to take effect and change what they inherit.
Go to each of your forms designer code class. Inside towards the top you will see the inherits statment. Change what it inherits.

Use Form(Of T) on VS Designer

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.

Can one move controls around in a form class derived from another form?

I have created a forms which are derived from another form thus:-
Public Class MyForm
' ...etc
End Class
Public Class MyDerivedForm
Inherits MyBaseForm
' ...etc
End Class
Public Class MyOtherDerivedForm
Inherits MyBaseForm
' ...etc
End Class
This works quite nicely and I can add controls to the derived form using the form designer. But I'd like to move some of the inherited controls around a bit on MyDerivedForm without disturbing MyBaseForm or MyOtherDerivedForm. I can't see any way of doing this on the forms designer.
Is it possible to do this (preferably with the designer but with code if necessary)?
This is not a typical VB.NET problem so not so sure what's going on here. You'll get the lock icon on the inherited controls and a grayed-out Properties window for an inherited control when the Modifiers property of the control in the base class is Private. The Winforms designer observes the accessibility of the base class member. Private members can't be messed with. The default value for Modifiers is Friend in VB.NET, Private in C#.
Make it Friend to allow the derived form class to modify the control properties. If the base form class lives in another assembly then Friend isn't good enough, you'll need Public.
The Anchor property can be an issue, but only if you anchor to the right or bottom. The control has a knack for ending up in the wrong spot when the derived form has a different size from the base form if the control is anchored that way. Simply avoided by not anchoring at the right/bottom in the base class and changing the anchor in the derived class.
In my VB.NET WinForms application I have inherited forms and I can just grab the inherited controls in the designer and move them about as I would with non-inherited controls on the form.
However I have noticed two things in the past that stop this. If you change the position of the controls on the base form, or change some of the positioning properties (such as anchor or docking), then this can (but not always) move your inherited controls. Also I couldn't move some of my inherited controls in an earlier version of .NET (2.0 I believe), but I never figured out the cause for that so I had to resort to changing the locations via the property grid.

Accessing to control inside of usercontrol

I am making an usercontrol with only one textbox so basically I expect that properties of textbox have to be applied to whole usercontrol.
That means (for example) that I would like from outside of usercontrol (in main program which contain those usercontrol) to get value of those (intern) textbox's selectionstart property.
But I can't find a way to do this except in creating a new public property of my UC.
I suppose that here should be some better way because textbox have many properties which may be needed to read (or maybe write) from main program and making another public property in UC for every internal property of textbox don't seems like "way to go" for me.
Any advice on how to get properties of internal control in UC from main program?
you may inherit your usercontrol from textbox control,liKe:
Class MyTextbox
inherits TextBox
End class
and then try to override, overload and access the events and properties you want.
you can check the following links,
1- For textbox inheritance example
2- Answered Question in Satckoverflow
Will not a regular FindControl check solve this?

Creating a Partial Class for a Form

I would like to create a partial class for my form. I have a lot of events, and it gets messy, so I would like to break up sections into their own files.
The problem: When I create a partial class of my form, say:
Partial Public Class Form1
End Class
Visual Studio decides I need another form for this partial class.
Questions:
1. How do I create a partial class for a form?
2. If I cant do that, how can I break up all the events in my form into different files?
Yeah, it does. As soon as you drop a control on this phantom form, you'll get the design-time code (InitializeComponent) generated into that source code file. This is compatibility behavior for .NET 1.x, it didn't support the Partial keyword. Which will break the build, there are now two of them. It is somewhat avoidable with careful clicking, but you know it's going to happen sooner or later.
Other things go wrong too btw, the designer can no longer track an event handler when you move it from one file to another. And will readily let you add another, a much trickier source of bugs.
This just doesn't work very well, abandon hope of relying on it to solve your problem.
The generic diagnostic is that a convoluted user interface begets convoluted code. But that ship has sailed, no doubt. A more structural solution is pursuing the MVC model, separating the data from the view of the data. You'll still have a lot of event handlers but they won't do anything more than calling a method of a class that does the real work. Whose source code can of course live in another source code file. The typical hangup is that Windows Forms has no support whatsoever built in for this, you have to craft it by hand. Nothing similar to the MVVM model in WPF.
Something that can work well is isolating control + code into a separate UserControl. You have to do so carefully though, you don't want to have to add a bunch of properties and events that expose internal controls.
Sometimes I create partial classes for better readibility, especially when I have very large classes.
But when I click on the partial class, then the VS IDE will open the form editor showing me an empty form. If I do not care, than I could damage the main form (it seems to be a bug of VS 2008/2010)
A possibility could be using DesignerCategoryAttribute Class
Mark the partial class with the attribute "code".
<System.ComponentModel.DesignerCategory("code")>
Partial Class Form1
End Class
In this way when you click on the file, you open the class in the code editor.
Of course this will apply to all files, also to the main form file.
If you want to edit again your form in the form editor, you have to quote the attribute:
'<System.ComponentModel.DesignerCategory("code")>
Some more details here.
While it does not answer the original question, I found using regions made my code a little more manageable/readable.
#Region "RegionA"
#End Region
I orginally called this method a "hack", thus the comment below.
Not sure what you mean be "Visual Studio decides you need another form", however, are you sure the new Form1 partial class is declared in the corresponding original namespace?
All partial classes for a given .NET type must be declared in the same namespace of course (whatever files they're stored on).
I appreciate the answers given by Hans and I'm not disputing these at all. It is curious though that in Visual Studio 2010, when you create a form called say Main you get a Main.designer.vb which is a partial class. It says 'Partial Class Main' at the top. This class doesn't open a form when clicked. It also includes reference to Event Handlers. So I was wondering how do they get around this? Is there a way to create one of these 'special' partial classes that work as we would expect.
I noticed that when I created a Form Partial class, that the icon went from a class icon to a form icon. The icon associated with the Main.designer.vb file looks like a class icon with a arrow.
what worked for me (VS 2010) was naming Form1 class, already saved in Form1.vb with its own designer (Form1.Designer.vb) as:
Public Class Main 'saved in Form1.vb
VS updated the name in the designer as:
Partial Class Main 'saved in Form1.Designer.vb
then I created another "partial class" with the same name:
Partial Class Main 'saved in Main.vb
Whether I am editing Form1.vb or Main.vb VS shows me on the top navigation pan all the routines, functions, subs, even background workers and timers. For event handlers, to avoid the loophole mentioned earlier (you click on a control in the layout designer and a brand new event handler will be created in the original Form1.vb) I go:
Partial Public Class Main 'in Form1.vb file
Private Sub SomeControl_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SomeControl.Click
Call SomeControlClick(sender, e)
End Sub
End Class
Partial Public Class Main 'then in Main.vb file
Private Sub SomeControlClick(ByVal sender As Object, ByVal e As System.EventArgs)
'blah blah
End Sub
End Class