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:
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:
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.