How to do a collection property inside another collection in user control - vb.net

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

Related

Combine two tables into one entity framework? (SQLite)

I am using the EntityFramework.SQLite library and for the life of me can not figure out how to combine two tables together into a temporary table for display purposes in xaml code.
Here's the code for my two tables I want to combine which is about all I am using right now besides a class for my temp table called CategoryList (this is part of the business/data logic dll library):
Partial Public Class CategoryList
Public Sub New()
Me.CategoryInfo = New CategoryReference
'Me.CategoryCode = New HashSet(Of CategoryCodes)
Me.CategoryCodes = New CategoryCodes
End Sub
Public Property MyId As Integer
<Key, ForeignKey("CodeID")>
<Required>
Public Property CodeID As Integer
<Key, ForeignKey("CategoryID")>
Public CategoryID As Integer
'Public Property CategoryCode As ICollection(Of CategoryCodes)
Public Property CategoryInfo As CategoryReference
' Public Property CategoryInfo As ICollection(Of CategoryReference)
Public Property CategoryCodes As CategoryCodes
End Class
<Table("CategoryCodes")>
Public Class CategoryCodes 'category shortnames/codes
<MaxLength(100)>
<Required>
Public Property CategoryCode As String
Get
Return _CategoryCode
End Get
Set(value As String)
_CategoryCode = value
End Set
End Property
Private _CategoryCode As String
'<NotNull>
' <PrimaryKey>
'<Unique(Name:="UQ__CategoryCodes__0000000000000081_CategoryCodes", Order:=0)>
<Key>
<Required>
Public Property CodeID As Integer
Get
Return CategoryCode
End Get
Set(value As Integer)
_CodeID = value
End Set
End Property
Private _CodeID As Integer
End Class
<Table("CategoryReference")>
Partial Public Class CategoryReference 'table design for category data
<MaxLength(100)>
Public Property CategoryName As String
Get
Return _CategoryName
End Get
Set(value As String)
_CategoryName = value
End Set
End Property
Private _CategoryName As String
<MaxLength(100)>
Public Property CategoryDescription As String
Get
Return _CategoryDescription
End Get
Set(value As String)
_CategoryDescription = value
End Set
End Property
Private _CategoryDescription As String
'<Unique(Name:="UQ__CatagoryReference__000000000000005F_CatagoryReference", Order:=0)>
<ForeignKey("CodeID")>
<Required>
Public Property CodeID As Integer
Get
Return _CodeID
End Get
Set(value As Integer)
_CodeID = value
End Set
End Property
Private _CodeID As Integer
'<Unique(Name:="UQ__CatagoryReference__000000000000005A_CatagoryReference", Order:=0)>
<Key>
<Required>
Public Property CategoryID As Integer
Get
Return _CategoryID
End Get
Set(value As Integer)
_CategoryID = value
End Set
End Property
Private _CategoryID As Integer
End Class
It may seem long but the tables are very simple and the get/set blocks make it look long (A vb.net editor can turn them into simple property's if she/he wishes). I may be using the CategoryList class wrong but here's where I use it in my xaml datasource in my main application code (I have business logic/data processing in a dll library):
Private Property ViewModel As List(Of UIELLUWP.DataAccess.CategoryList)
Dim categories As New UIELLUWP.DataAccess.SQLiteDb
ViewModel = categories.Categories.ToList
Errors received with current code:
I receive an error that Table "CategoryList" does not exist when I run the above code.
my solution I found out to this question was to add asnotracking because tracking was taking place.

Property Set not fire when deserialize(xml) a list of

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

Custom CollectionEditor never triggers a property's "set" method

I am trying to implement a way of persisting a collection in a custom settings class. I have successfully created the settings class (inheriting ApplicationSettingsBase) and can save properties using the built-in editors on a PropertyGrid, but my custom implementation of a property grid for collections doesn't persist any of the values I add. Here's my code:
Imports System.Configuration
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.ComponentModel.Design
Public Class CustomSettings
Inherits ApplicationSettingsBase
<UserScopedSetting()> _
<DefaultSettingValue("White")> _
Public Property BackgroundColor() As Color
Get
BackgroundColor = Me("BackgroundColor")
End Get
Set(ByVal value As Color)
Me("BackgroundColor") = value
End Set
End Property
<UserScopedSetting()> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
<Editor(GetType(CustomStringCollectionEditor), GetType(UITypeEditor))> _
Public Property EmailAddresses() As Collection
Get
EmailAddresses = Me("EmailAddresses")
End Get
Set(ByVal value As Collection)
Me("EmailAddresses") = value
End Set
End Property
End Class
Public Class CustomStringCollectionEditor
Inherits CollectionEditor
Public Sub New()
MyBase.New(GetType(Collection))
End Sub
Protected Overrides Function CreateInstance(ByVal itemType As System.Type) As Object
Return String.Empty
End Function
Protected Overrides Function CreateCollectionItemType() As System.Type
Return GetType(String)
End Function
End Class
I set a breakpoint on the Set methods for both the BackgroundColor property and the EmailAddresses property. The BackgroundColor property works as it should - it breaks on the Set statement and stores the property correctly. But when I close the custom CollectionEditor dialog, the EmailAddresses "Set" method is never called. How can I get my custom editor to actually save the property once it's done being edited?
I think I fixed it (with help from this question). I added an override to the EditValue function in my custom editor. Here is the code:
Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
Dim result As Object = MyBase.EditValue(context, provider, value)
DirectCast(context.Instance, CustomSettings).EmailAddresses = DirectCast(result, List(Of String))
Return result
End Function
I also moved from a collection to a list - I read somewhere that was a safer way to go. I also added a constructor to my CustomSettings class that set the EmailAddresses property to a new List(Of String) if it was unset to begin with. I found that the first time it ran, I could edit the list and add items, but they wouldn't be persisted:
Public Sub New()
If Me("EmailAddresses") Is Nothing Then
Me("EmailAddresses") = New List(Of String)
End If
End Sub
And now it's all working like it should. But if this isn't the best way or there's an easier way to do it, please chime in.

OData made from objects

Lets say I have a class called "Item" and "SubItems"
Public Class SubItem
Private _SubItemName As String
Public Property SubItemName() As String
Get
Return _SubItemName
End Get
Set(ByVal value As String)
_SubItemName = value
End Set
End Property
End Class
<DataServiceKey("Name")> _
Public Class Item
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _SubItems As List(Of SubItem)
Public Property SubItems() As List(Of SubItem)
Get
Return _SubItems
End Get
Set(ByVal value As List(Of SubItem))
_SubItems = value
End Set
End Property
End Class
How would I create a service that would return a list of Items and upon looking up an individual item I would be able to see the sub items.
You can check out WCF Data Servies reflection provider, e.g.,
http://blogs.msdn.com/b/alexj/archive/2010/06/11/tip-56-writing-an-odata-service-using-the-reflection-provider.aspx
http://msdn.microsoft.com/en-us/library/dd728281.aspx
Hope this helps.

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?