Search code examples
vb.netinterfaceimplements

Implementing Interface from C# to VB.NET


I had downloaded a C# project and wanted to work on VB.Net so I decided to convert that from C# to VB.NET and I encountered some problems when it came to implementing interfaces. I keep getting errors in VB.NET about implementation about how I must have Read-Only or Write-Only specifiers. I want to get rid of this error but I don't know how I can achieve this.

I have Three Files:

  1. CustomPaintRichText.vb
  2. IUnderlineableSpellingControl.vb
  3. ISpellingControl.vb

The same goes with C#, however in C# it works fine and I want to try to get it to work exactly like that in VB.net.

CustomPaintRichText.vb:

Public Class CustomPaintRichText
Inherits RichTextBox
Implements IUnderlineableSpellingControl

Public m_underlinedSections As Dictionary(Of Integer, Integer)
Public m_protectedSections As Dictionary(Of Integer, Integer)
Public m_ignoredSections As Dictionary(Of Integer, Integer)
Public Property UnderlinedSections() As Dictionary(Of Integer, Integer)
    Get
        If m_underlinedSections Is Nothing Then
            m_underlinedSections = New Dictionary(Of Integer, Integer)()
        End If
        Return m_underlinedSections
    End Get
    Set(value As Dictionary(Of Integer, Integer))
        m_underlinedSections = value
    End Set
End Property

Public WriteOnly Property ProtectedSections() As Dictionary(Of Integer, Integer)
    Set(value As Dictionary(Of Integer, Integer))
        m_protectedSections = value
    End Set
End Property

Public WriteOnly Property IgnoredSections() As Dictionary(Of Integer, Integer)
    Set(value As Dictionary(Of Integer, Integer))
        m_ignoredSections = value
    End Set
End Property

Private spellingEnabled As Boolean
Private spellingAutoEnabled As Boolean
Private m_isPassWordProtected As Boolean

Private penColour As Pen
Public Property WhatPenColour() As Pen
    Get
        Return penColour
    End Get
    Set(value As Pen)
        penColour = value
    End Set
End Property

Public Property IsSpellingEnabled() As Boolean
    Get
        Return spellingEnabled
    End Get
    Set(value As Boolean)
        spellingEnabled = value
    End Set
End Property

Public Property IsSpellingAutoEnabled() As Boolean
    Get
        Return spellingAutoEnabled
    End Get
    Set(value As Boolean)
        spellingAutoEnabled = value
        If Not spellingEnabled Then
            spellingEnabled = value
        End If
    End Set
End Property

Public Property IsPassWordProtected() As Boolean
    Get
        Return m_isPassWordProtected
    End Get
    Set(value As Boolean)
        m_isPassWordProtected = value
    End Set
End Property
End Class

IUnderlineableSpellingControl.vb:

Public Interface IUnderlineableSpellingControl
   Inherits ISpellingControl
   Inherits IUnderlineable
End Interface

ISpellingControl.vb:

Public Interface ISpellingControl
<Browsable(True)> _
Property IsSpellingEnabled() As Boolean
Property SelectionStart() As Integer
Property SelectionLength() As Integer
Property SelectedText() As String
Property Text() As String
Property ContextMenuStrip() As ContextMenuStrip
Property WhatPenColour() As Pen
Property Parent() As Control
Event Disposed As EventHandler
Event Enter As EventHandler
Event TextChanged As EventHandler
Property [ReadOnly]() As Boolean
ReadOnly Property IsPassWordProtected() As Boolean
Sub Cut()
Sub Copy()
Sub Paste(clipFormat As DataFormats.Format)
Sub [Select](start As Integer, length As Integer)
Function Focus() As Boolean
Sub Invalidate(invalidateChildren As Boolean)
WriteOnly Property IgnoredSections() As Dictionary(Of Integer, Integer)
End Interface

If I keep the cursor carret next to Implements IUnderlineableSpellingControl and hit ENTER key, within the CustomPaintRichText.vb class, I get:

Public Property ContextMenuStrip1 As ContextMenuStrip Implements ISpellingControl.ContextMenuStrip

Public Sub Copy1() Implements ISpellingControl.Copy

End Sub

Public Sub Cut1() Implements ISpellingControl.Cut

End Sub

Public Event Disposed1(sender As Object, e As EventArgs) Implements ISpellingControl.Disposed

Public Event Enter1(sender As Object, e As EventArgs) Implements ISpellingControl.Enter

Public Function Focus1() As Boolean Implements ISpellingControl.Focus

End Function

Public WriteOnly Property IgnoredSections1 As Dictionary(Of Integer, Integer) Implements ISpellingControl.IgnoredSections
    Set(value As Dictionary(Of Integer, Integer))

    End Set
End Property

Public Sub Invalidate1(invalidateChildren As Boolean) Implements ISpellingControl.Invalidate

End Sub

Public ReadOnly Property IsPassWordProtected1 As Boolean Implements ISpellingControl.IsPassWordProtected
    Get

    End Get
End Property

Public Property IsSpellingEnabled1 As Boolean Implements ISpellingControl.IsSpellingEnabled

Public Property Parent1 As Control Implements ISpellingControl.Parent

Public Sub Paste1(clipFormat As DataFormats.Format) Implements ISpellingControl.Paste

End Sub

Public Property ReadOnly1 As Boolean Implements ISpellingControl.ReadOnly

Public Sub Select1(start As Integer, length As Integer) Implements ISpellingControl.Select

End Sub

Public Property SelectedText1 As String Implements ISpellingControl.SelectedText

Public Property SelectionLength1 As Integer Implements ISpellingControl.SelectionLength

Public Property SelectionStart1 As Integer Implements ISpellingControl.SelectionStart

Public Property Text1 As String Implements ISpellingControl.Text

Public Event TextChanged1(sender As Object, e As EventArgs) Implements ISpellingControl.TextChanged

Public Property WhatPenColour1 As Pen Implements ISpellingControl.WhatPenColour

Public Sub CustomPaint1() Implements IUnderlineable.CustomPaint

End Sub

Public Property IsSpellingAutoEnabled1 As Boolean Implements IUnderlineable.IsSpellingAutoEnabled

Public Event KeyDown1(sender As Object, e As KeyEventArgs) Implements IUnderlineable.KeyDown

Public WriteOnly Property ProtectedSections1 As Dictionary(Of Integer, Integer) Implements IUnderlineable.ProtectedSections
    Set(value As Dictionary(Of Integer, Integer))

    End Set
End Property

Public Sub RemoveWordFromUnderliningList1(wordStart As Integer) Implements IUnderlineable.RemoveWordFromUnderliningList

End Sub

Public Event SelectionChanged1(sender As Object, e As EventArgs) Implements IUnderlineable.SelectionChanged

Public Property UnderlinedSections1 As Dictionary(Of Integer, Integer) Implements IUnderlineable.UnderlinedSections

And when I make changes to the CustomPaintRichText from a form, I will have extra additional controls and ultimately nothing works.

The error is in Implements IUnderlineableSpellingControl. It is underlined saying that: 'CustomPaintRichText' must implement 'Event Disposed(sender As Object, e As System.EventArgs)' for interface 'ISpellingControl'. This is one of 30 errors along with the ..must implement..for interface.

Here's the error list if you want to see what kind of errors I'm getting.

Here are the .cs files in case:

  1. CustomPaintRichText.cs
  2. IUnderlineableSpellingControl.cs
  3. ISpellingControl.cs

Solution

  • Congratulations, you made Hans Passant go "Ugh!" :)

    Speaking to his point, though, mixing and matching assemblies compiled from VB, C#, C++/CLI, F#, or whatever, is generally encouraged in the .NET world, and is the practical solution to your problem. However, if you insist on transforming this C# project into its VB equivalent, one needs to understand the differences in how interfaces get implemented between these two languages.

    C# has two styles of implementation: implicit and explicit (see http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx). VB has only an explicit style, which doesn't work quite the same as C# (see https://msdn.microsoft.com/en-us/library/28e2e18x.aspx).

    All of those "must implement" errors mean pretty much what they say: You must use the Implements keyword on the appropriate members of your subclass, because VB doesn't do implicit implementations of interfaces. That's a C# thing. When you hit the ENTER key with the cursor caret next to Implements IUnderlineableSpellingControl, the IDE generated template code for the affected (apparently missing) members, complete with Implements. It did that in trying to be helpful, but in this case you have to look over the code and put in the Implements clauses where they're needed (and probably get rid off that template code).

    C# has a neat implicit style where it will automatically "wire-up" implementations by matching member names between your class and the interfaces being implemented. Should there be more than one interface that have the same member (with the same signature), they will all be implemented with the very same member in your class (see http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx). This can be a wonderful or not-so-good thing depending on the situation.

    C# has a limited explicit style. One simply defines a member in the named in the format of InterfaceName.MemberName (see https://msdn.microsoft.com/en-us/library/ms173157.aspx).

    VB has only its explicit style, but it allows for a list of interface members in the Implements clause so that they all get implemented by the very same member in your class. This is the work-around for C# implicit implementations that hookup multiple interfaces.

    Finally, there are some sources which claim that VB cannot do re-implementations of an interface on a subclass of a superclass that already has it implemented (e.g. http://www.dotnetheaven.com/article/how-to-re-implement-interfaces-in-vb.net). I do not know if that was ever true, but I can aver that the VB of VS 2012 and later allows for such re-implementations.