VB.NET WinForms implementing an interface - vb.net

VB.NET
I want some WinForms to implement an interface, and be able to pass these to a procedure which can 'see' the implemented properties as well as the 'standard methods' of a Form. This is what I have so far...
Public Interface IMyInterface
Property MyProperty As String
End Interface
Public Class MyForm
Implements IMyInterface
Private _MyProperty As String
Public Property MyProperty() As String Implements IMyInterface.MyProperty
Get
Return _MyProperty
End Get
Set(ByVal value As String)
_MyProperty = value
End Set
End Property
End Class
then, elsewhere I have my method as follows...
Public Sub DoSomething(MyForm As IMyInterface)
MyForm.MyProperty = "x"
MyForm.ShowDialog()
End Sub
The obvious problem is that the compiler doesn't know what .ShowDialog is, and if I pass my form in as 'MyForm As Form' it doesn't know what 'MyProperty' is. I understand the reasons for this, but not how to solve this problem. Is a simple casting to Form the correct way to address this?
Many thanks.

You need to inherit System.Windows.Forms.Form to gain all regular form functionality and then Implement IMyInterface.
Public Class MyForm
Inherits System.Windows.Forms.Form
Implements IMyInterface
Passing MyForm As IMyInterface into the DoSomething() method is fine, however to use the regular form methods you'll need to cast it. Alternatively you could pass in the Form and then cast to IMyInterface, your choice.
Public Sub DoSomething(MyIForm As IMyInterface)
MyIForm.MyProperty = "x"
Dim MyForm As Form = TryCast(MyIForm, Form)
MyForm.ShowDialog()

Another aproach can be using your own base class
Public Class MyBaseForm
Inherits System.Windows.Forms.Form
Public Property MyProperty As String
End Class
Then all your forms can inherit that base form
Public Class MyForm
Inherits MyBaseForm
End Class
And you can use property and standard method of System.Windows.Forms.Form without casting
Public Sub DoSomething(someform As MyForm)
someform.MyProperty = "Some value"
someform.ShowDialog()
End Sub

Related

VB.Net Class Inherit Sub New

I'm currently trying to convert some basics in C# class methods into VB, and I'm having some difficulties.
Say we have two classes, baseClass and newClass
Public Class baseClass
Public Sub New(ByVal obj As Object)
'... do something here
End Sub
End Class
Public Class newClass
Inherits baseClass
Public Sub New(ByVal obj as Object)
'... do something here
End Sub
end Class
However, whenever I tried to declear something like
dim nc as newClass(myObj)
I kept getting an error telling me that
First statement of this 'Sub New' must be a call to 'MyBase.New' or 'MyClass.New' because base class 'baseClass' of 'newClass' does not have an accessible 'Sub New' that can be called with no arguments.
When I was trying to do something like, if written in C#, like this
public partial class newClass : baseClass
{
public newClass(Object obj) : baseClass(obj)
{
// do something here
}
}
I understand that the debugger is telling me just add an empty public sub new() in baseClass, but that's not what I'm trying to do, I wanted it to invoke the other constructor, so hopefully someone can point me in the right direction, since I've been trying to find an easy conversion guide but I couldn't find any.
Any answer is much appreciated.
Public Class newClass
Inherits baseClass
Public Sub New(ByVal obj as Object)
MyBase.New(obj)
End Sub
end Class

How do I get a superclass to reference a property in a subclass when the subclass invokes the superclass' method?

The superclass:
Public MustInherit Class Product
Friend _shortName as String = Nothing
Public ReadOnly Property Name as String
Get
return _shortName
End Get
End Property
End Class
The Sub class
Public Class MyProduct : Inherits Product
Friend Shadows _shortName as String = "MyProd"
End Class
So, in the immediate console when I'm debugging, I do:
Dim product as new MyProduct
product.Name ' => Nothing
product.Name should be "MyProd" - but it isn't. How do I set this up correctly, so that the the property defined in the superclass accesses the field defined in the subclass?
There is no way for the base class to access the shadowed version of the field. Shadows should be avoided unless it is absolutely necessary. For something like this, you should just change the value of the base field from the derived class. There is no need to shadow it:
Public Class MyProduct : Inherits Product
Public Sub New()
_shortName = "MyProd"
End Sub
End Class
It's worth mentioning that, unless you really need it to be scoped as Friend, the _shortName field in the base class should be scoped as Protected.
Although, in this example, it looks like you probably want all derived classes to provide the name. In that case, there are two ways to accomplish that. You could require the name as a parameter in the base class' constructor:
Public MustInherit Class Product
Public Sub New(shortName As String)
_shortName = shortName
End Sub
Friend _shortName As String = Nothing
Public ReadOnly Property Name As String
Get
Return _shortName
End Get
End Property
End Class
Public Class MyProduct : Inherits Product
Public Sub New()
MyBase.New("MyProd")
End Sub
End Class
In this case, the _shortName doesn't even need to be Friend or Protected. It should ideally be scoped as Private.
Or, you could simply declare the property as MustOverride:
Public MustInherit Class Product
Public MustOverride ReadOnly Property Name As String
End Class
Public Class MyProduct : Inherits Product
Public Overrides ReadOnly Property Name As String
Get
Return "MyProd"
End Get
End Property
End Class

How to use classes as properties only?

I have been trying to do this for a long time but I can't find anything anywhere. I think I am not searching it as it should...
A little example:
Class MainClass
Property ExampleProperty As New ExamplePropertyClass
Private Class ExamplePropertyClass
Sub DoSomething()
End Sub
End Class
End Class
In the previous code the ExamplePropertyClass is used as an property of the MainClass.
There is always an error that says I can't expose a private class as propery.
But how is it possible to make only the property "Visible", I mean The user who is going to use the code should only use the property and not the class, how can the class be not inherited or visible?
What is property actually syntactic sugar for setter and getter.So mostly it is default public
You declare class as private. So it will be invisible outside. Then there is conflict if it be not visible then how people will know to assign and get that object without knowing its type. So that type should be public and visible
dim m as new MainClass()
m.ExampleProperty=? ' What is ExampleProperty ?int , object. So it should not be unknown
Another way you claim that you are not going to use that property outside.This way it is ok to have private class inside.
'Explicitly make property to be used only within class
Private Property ExampleProperty As ExamplePropertyClass
You do this with interfaces:
Public Interface IDoesSomething
Sub DoSomething()
End Interface
Public Class MainClass
Public Sub New()
m_example = New InternalClass
End Sub
Private m_example As IDoesSomething
Public ReadOnly Property Example() As IDoesSomething
Get
Return m_example
End Get
End Property
Private Class InternalClass
Implements IDoesSomething
Public Sub DoSomething() Implements IDoesSomething.DoSomething
End Sub
End Class
End Class

how to access class from inherited class

I have two classes:
class class2
inherits class1
public sub modify()
'modify property of class1
end sub
end class
How can I modify class1 in a sub in class2?
You just call it. Example:
Public Class class1
Private _Value As String = String.Empty
Property Value() As String
Get
Return _Value
End Get
Set(ByVal value As String)
_Value = value
End Set
End Property
End Class
Public Class class2
Inherits class1
Public Sub modify()
Value = "modified"
End Sub
End Class
And to show it works:
Dim c2 As New class2
c2.modify()
MessageBox.Show(c2.Value)
You are asking about properties, note that only protected and public properties are visible to inherited classes.
You need the MyBase keyword when you are overriding an existing function in the parent class. Other protected or public properties or functions can be accessed regulary without any special keyword.
One tip I wanted to add to the above comments regarding accessing base class info is where you have a base class without a default contructor or want to use a specific constructor This is a good opportunity to use Mybase. You have to call the constructor before any additional actions take place in this scenario.
Public Class MyClass
Inherits baseClass
Public Sub New()
mybase.new("Oranges")
End Sub
End Class
Public Class baseClass
Private _someVariable as String
Public Sub New(byval passedString as string)
_someVariable = passedString
End Sub
End Class

Can I inherit from a generic class without specifying a type?

I have the following sample code in a VB.NET console application. It compiles and works, but feels like a hack. Is there a way to define EmptyChild so that it inherits from Intermediate(Of T As Class) without using the dummy EmptyClass?
Module Module1
Sub Main()
Dim Child1 = New RealChild()
Child1.Content = New RealClass()
Dim Child2 = New EmptyChild()
Console.WriteLine("RealChild says: " & Child1.Test)
Console.WriteLine("EmptyChild says: " & Child2.Test)
Console.ReadLine()
End Sub
Public Class EmptyClass
End Class
Public Class RealClass
Public Overrides Function ToString() As String
Return "This is the RealClass"
End Function
End Class
Public MustInherit Class Base(Of T As Class)
Private _content As T = Nothing
Public Property Content() As T
Get
Return _content
End Get
Set(ByVal value As T)
_content = value
End Set
End Property
Public Overridable Function Test() As String
If Me._content IsNot Nothing Then
Return Me._content.ToString
Else
Return "Content not initialized."
End If
End Function
End Class
Public MustInherit Class Intermediate(Of T As Class)
Inherits Base(Of T)
'some methods/properties here needed by Child classes
End Class
Public Class RealChild
Inherits Intermediate(Of RealClass)
'This class needs all functionality from Intermediate.
End Class
Public Class EmptyChild
Inherits Intermediate(Of EmptyClass)
'This class needs some functionality from Intermediate,
' but not the Content as T property.
Public Overrides Function Test() As String
Return "We don't care about Content property or Type T here."
End Function
End Class
End Module
The other way to do this would be to move the generic code out of the Base class and then create 2 Intermediate classes like this:
Public MustInherit Class Intermediate
Inherits Base
'some methods/properties here needed by Child classes
End Class
Public MustInherit Class Intermediate(Of T As Class)
Inherits Intermediate
'implement generic Content property here
End Class
Then RealChild would inherit from the generic Intermediate and EmptyChild would inherit from the non-generic Intermediate. My problem with that solution is that the Base class is in a separate assembly and I need to keep the code that handles the generic type in that assembly. And there is functionality in the Intermediate class that does not belong in the assembly with the Base class.
Yes, you need to specify a type parameter when you inherit, or your EmptyChild must be generic as well. But, you don't have to dummy up a EmptyClass - just use Object as your type parameter:
Public Class EmptyClass
Inherits Intermediate(Of Object)
End Class