Property Set not fire when deserialize(xml) a list of - vb.net

I got a class containing integer,bool,string and list (of integer). Each variable that need to be serialize in that class has a public property. When i deserialize my class via XmlSerializer the public property of each variable is call. Except the variable that are list of. The List of varaibles are weel deserialisze but the property setter isn't called.
Here is the property :
Public Property Ana_Offset As List(Of Integer)
Get
Return _Ana_Offset
End Get
Set(value As List(Of Integer))
Tmp_Val = _Ana_Offset
_Ana_Offset = value
RaiseEvent VariableChanged(_Ana_Offset, Tmp_Val, "_Ana_Offset", 0)
End Set
End Property
The class is something like this
<Serializable()> Public Class SACCVar
Private _Code_Produit As String
Private _Ana_Offset As New List(Of Integer)
Public Event VariableChanged(ByVal Val As Object, ByVal Old_Val As Object, desc As String, index As Integer)
End Class
The strange fact i just realise while posting is that i got no Set "event" but the get event is fired wit no data return, but for other variable the get isn't fired..?
Thanks for help

Related

In vb.net, defining a dictionary type in a class

New to using a Dictionary list.
I have an api that is returning a "task object" defined as:
id As Integer
options As Dictionary(string, string)
So I am defining a class called Task to store the returned "task object".
Public Class Task
Private _id As Integer
Public Property Id() As Integer
Get
Return _id
End Get
Set(value As Integer
_id = value
End Set
End Property
Private _optionlist As New List(Of Option)
Public Property OptionList() As List(Of Option)
Get
Return _optionlist
End Get
Set(ByVal value As List(Of Option))
_optionlist = value
End Set
End Property
End Class
Public Class Option
Private _key As String
Public Property Key() As String
Get
Return _key
End Get
Set(value As String)
_key = value
End Set
End Property
Private _value As String
Public Property Value() As String
Get
Return _value
End Get
Set(value As String)
_value = value
End Set
End Property
End Class
I will assign the "task object" returned from the api to this Task class.
I defined options as a list. Is that correct?
I will also have to read the option in my class and later repopulate it to send back to the api via function call.
Could use some help...thanks.
You can add the property to the class directly:
Public Class Task
Private _id As Integer
Private options As Dictionary(of string, string)
You can also create Get and Set methods for the "options" parameter.

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:
CustomPaintRichText.vb
IUnderlineableSpellingControl.vb
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:
CustomPaintRichText.cs
IUnderlineableSpellingControl.cs
ISpellingControl.cs
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.
C# allows you to implement a WriteOnly or ReadOnly property with a read/write property. (VB 2015 also allows this).
You can easily work around this prior to VB 2015 - here's an example for your IsPasswordProtected implementation:
Private ReadOnly Property ISpellingControl_IsPassWordProtected() As Boolean Implements ISpellingControl.IsPassWordProtected
Get
Return IsPassWordProtected
End Get
End Property
Public Property IsPassWordProtected() As Boolean
Get
Return isPassWordProtected_Renamed
End Get
Set(ByVal value As Boolean)
isPassWordProtected_Renamed = value
End Set
End Property
The 'Implements' goes on the new ReadOnly property which calls the existing read/write property.

How to do a collection property inside another collection in user control

I have a user control with a property "Rules" that is a generic list.
Every "rule" is associated to a combobox control and i have to create a property to host data for the combobox. I used another generic list to accomplish this.
In design works well, i can add items normally in property grid, but when i run the program the values are not maintained.
Rules property:
Private _regras As New List(Of ParametrosColunasGrid)
<Category("Ecletica")> _
<Browsable(True)> _
<System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)>
Public Property Regras() As List(Of ParametrosColunasGrid)
Get
Return _regras
End Get
Set(value As List(Of ParametrosColunasGrid))
_regras = value
End Set
End Property
Public Class ParametrosColunasGrid
'...
Private _itens_Combo As New List(Of ItemComboBox)
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property ItensCombo As List(Of ItemComboBox)
Get
Return _itens_Combo
End Get
Set(value As List(Of ItemComboBox))
_itens_Combo = value
End Set
End Property
'...
End Class
ItemComboBox Class:
<Serializable()>
Public Class ItemComboBox
Public Property Value As String
Public Property Key As String
Public Overrides Function ToString() As String
Return _Value
End Function
End Class

Keep two-way binding when whole object has changed

I have a class:
Public Class TestClass
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Sub OnNotifyChanged(ByVal pName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(pName))
End Sub
Private _One As Integer
Private _Two As Integer
Public Sub New(ByVal One As Integer, ByVal Two As Integer)
_One = One
_Two = Two
End Sub
Public Property One() As Integer
Get
Return _One
End Get
Set(ByVal value As Integer)
_One = value
OnNotifyChanged("One")
End Set
End Property
Public Property Two() As Integer
Get
Return _Two
End Get
Set(ByVal value As Integer)
_Two = value
OnNotifyChanged("Two")
End Set
End Property
End Class
I can create an instance and bind two TextBoxes to the object:
Dim MyObject As New TestClass(1, 2)
TextBoxOne.DataBindings.Add("Text", MyObject, "One")
TextBoxTwo.DataBindings.Add("Text", MyObject, "Two")
Now I can change the TextBoxes or the object:
MyObject.Two = 3
..the object and TextBoxes are updated in two ways.
Now I want to update the whole object:
MyObject = New TestClass(3, 4)
...but this doesn't update the TextBoxes.
What am I doing wrong?
Your text boxes hold a reference to the first instance of the object you've created.
Now you're creating a second instance, supposedly in order to replace the existing instance, but the text boxes are unaware of the change.
You needs to either:
Pass the new instance to the text boxes (directly, as you assigned the first instance, or indirectly by having some "Model" object that both boxes are bound to).
Update the existing instance instead of replacing it with a new one (you can simply assign values to the fields, or create some "AssignFrom (other)" method, etc.)
Get yourself some other - more orderly - way of notifiying the controls that their underlying data source has changed / should be changed.

Generic Collections

In VB6, there used to be a Collection data type that would allow retrieval of an item in the collection by either its key or its ordinal. However, it wasn't strongly typed.
Now, with VB.Net, I am looking for a suitable replacement that is strongly type and could be used with a generic collection.
This is a simple example of what I want to do. The only problem is that the underlying collection class, BindingList, does not support efficient retrieval of an item by an alpha key, so I have to loop through the elements to get the item I am looking for. For large collections, this is not efficient.
I have looked though the various Collection type classes and have found no suitable replacement.
This is what I want to do, except for the looping that is done with the Item property.
Rather than just saying "Use Hash tables" or something like that, if you could, please include the detailed out as I have done for the short example below.
Public Class Car
Public Sub New(ByVal keyName As String, ByVal property1 As String)
_KeyName = keyName
_Property1 = property1
End Sub
Dim _KeyName As String
Public Property KeyName() As String
Get
Return _KeyName
End Get
Set(ByVal value As String)
_KeyName = value
End Set
End Property
Public _Property1 As String
Public Property Property1() As String
Get
Return _Property1
End Get
Set(ByVal value As String)
_Property1 = value
End Set
End Property
End Class
Public Class Cars
Inherits System.ComponentModel.BindingList(Of Car)
Public Overloads ReadOnly Property Item(ByVal key As String) As Car
Get
For Each CurrentCar As Car In Me.Items
If CurrentCar.KeyName = key Then
Return CurrentCar
End If
Next
Return Nothing
End Get
End Property
End Class
I believe you're looking for Dictionary<TKey, TValue>. In fact, if you do want your own collection class that's strongly typed and isn't (itself) generic, if you change your parent class to Dictionary<string, Car>, you should be all set. This all does, of course, assume that you add the cars to the collection with an explicit string key. If you want the lookup to be based on the value of a property in the collection, you'd do better either using or inheriting from List<Car> and using LINQ to query the list. You could then have...
Public Overloads ReadOnly Property Item(ByVal key As String) As Car
Get
Return (from c in Me where c.KeyName = key select c).SingleOrDefault()
End Get
End Property
Do you really need both access by key AND index?
If you do not, then use a Dictionary(Of String, Car), and use
- MyCol.Items("XXX") to retrieve an item by key (or the shorthand MyCol("XXX"))
- MyCol.ContainsKey("XXX") to test if a key exists in the collection
- For Each Entry as KeyValuePair(Of String, Car) in MyCol if you want to enumerate all objects AND their key
- For Each Entry as Car in MyCol.Values if you want to enumerate the entries without consideration for the key
If you need both access by index and key, I'm afraid your best bet is to use a List(of Car) and a Dictionary(of Car) rolled into one custom collection class, because I believe they went away from that kind of collection which is not really all that useful for most problems.
This is what I am thinking is my best solution. I welcome comments for a better way!
Imports Microsoft.VisualBasic
Public Class Car
Implements Xs(Of Car).IKeyName
Private _KeyName As String
Public Sub New(ByVal keyName As String, ByVal property1 As String)
_KeyName = keyName
_Property1 = property1
End Sub
Public Property KeyName() As String Implements Xs(Of Car).IKeyName.KeyName
Get
Return _KeyName
End Get
Set(ByVal value As String)
_KeyName = value
End Set
End Property
Public _Property1 As String
Public Property Property1() As String
Get
Return _Property1
End Get
Set(ByVal value As String)
_Property1 = value
End Set
End Property
End Class
Public Class Cars
Inherits System.ComponentModel.BindingList(Of Car)
Public Overloads ReadOnly Property Item(ByVal key As String) As Car
Get
For Each CurrentCar As Car In Me.Items
If CurrentCar.KeyName = key Then
Return CurrentCar
End If
Next
Return Nothing
End Get
End Property
End Class
Public Class X
Private _KeyName As String
Public Property KeyName() As String
Get
Return _Keyname
End Get
Set(ByVal value As String)
_Keyname = value
End Set
End Property
End Class
Public Class Xs(Of X)
Inherits Hashtable
Interface IKeyName
Property KeyName() As String
End Interface
Public Shadows Sub Add(ByVal item As IKeyName)
MyBase.Add(item.KeyName, item)
End Sub
Public Shadows ReadOnly Property Item(ByVal key As String) As x
Get
If Me.ContainsKey(key) Then
Return MyBase.Item(key)
Else
'If I mispell a key, I don't want to end up creating a new mispelled version, I want an error
Throw New Exception("Element with key " & key & " is not found")
End If
End Get
End Property
End Class
Public Class Cars2
Inherits Xs(Of Car)
End Class
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim MyCar As New Car("key1", "prop1")
'First approach
Dim MyCars As New Cars
MyCars.Add(MyCar)
Dim RetrievedCar As Car = MyCars.Item("key1") 'Inefficient retrieval by key (uses looping)
'Second approach
Dim Cars2 As New Cars2
Cars2.Add(MyCar)
Dim RetrievedCar2 As Car = Cars2.Item("key1") 'Can now efficiently retreive an item by its key
End Sub
The OrderedDictionary in the System.Collections.Specialized namespace can be accessed by index and by key, if you ever need that. But looking at your solution, it looks like a standard Dictionary, but less efficient because it forces a string type for keys.
Is there any reason you can't use the Dictionary .NET provides you, or another collection type that's already in .NET like OrderedDictionary?