I am doing an VB.Net WinForm Application. It is a migration of C#.
In C# I have a variable defined like this.
private static Dictionary<string, ExportFormatType> dicExtensiones =
new Dictionary<string, ExportFormatType> {
{".pdf", ExportFormatType.PortableDocFormat},
{".doc", ExportFormatType.WordForWindows},
{".xls", ExportFormatType.Excel},
{".rtf", ExportFormatType.RichText},
{".html", ExportFormatType.HTML40},
{".txt", ExportFormatType.Text}
};
And i migrated to this..
Private Shared dicExtensiones = New Dictionary(Of String, ExportFormatType) From
{{".pdf", ExportFormatType.PortableDocFormat},
{".doc", ExportFormatType.WordForWindows},
{".xls", ExportFormatType.Excel},
{".rtf", ExportFormatType.RichText},
{".html", ExportFormatType.HTML40},
{".txt", ExportFormatType.Text}}
Now I need to Loop through all ítems and get each value...
In C# is like this.
List<String> lista = new List<string>();
foreach (var item in dicExtensiones)
{
lista.Add(Enum.GetName(typeof(ExportFormatType), item.Value));
lista.Add("*" + item.Key);
}
The problem i have is that I do know how to migrate
Enum.GetName(typeof(ExportFormatType), item.Value);
to VB.Net, because Enum.GetName does not exists in VB.Net
How can I do it?
it can be like below in VB
Dim lista As List(Of [String]) = New List(Of String)()
For Each item As var In dicExtensiones
lista.Add([Enum].GetName(GetType(ExportFormatType), item.Value))
lista.Add("*" + item.Key)
Next
In VB, Enum is a keyword, as well as a class name, so you need to escape it in your code. The escaping syntax is similar to SQL:
[Enum].GetName
By escaping it, you're telling the compiler that you are referring to the identifier by that name rather than the keyword. For instance, you might also need to escape your own class or variable names on occasion:
Dim [property] As String = "belt, wallet with $50, casio watch"
or
Public Class [Class]
Public Property Teacher As String
Public Property Students As List(Of Student)
End Class
Though, in most cases it's preferable to just avoid it by thinking of a different name to use.
Related
I am trying to move selected items from one list to another.
This code doesn't work because "itemsToMove" is a reference type and is not holding the value but instead a reference to that list.
so when i change the list i get an enumerable exception.
Dim itemsToMove = FullList.SelectedItems()
For Each item As Object In itemsToMove
GroupList.Items.Add(item)
FullList.Items.Remove(item)
Next
Is there a way to tell "itemsTomove" to take the Value of FullList.SelectedItems() instead of a reference to the memory? basically clone that list?
i did some research and i found some terms such as Boxing and Un-boxing but i do not really know if that is relevant.
If i cannot do that, does that mean This is the only (cleanest) way to do what i want?
Dim itemsToMove As Collection = New Collection()
For Each i As Object In FullList.SelectedItems()
itemsToMove.Add(i)
Next
For Each item As Object In itemsToMove
GroupList.Items.Add(item)
FullList.Items.Remove(item)
Next
If you want a copy of a reference type then it is up to you to create, yes. In this particular case, you wouldn't do it like you showed though. You can just do this:
For Each selectedItem In FullList.SelectedItems.Cast(Of Object)().ToArray()
FullList.Items.Remove(selectedItem)
GroupList.Items.Add(selectedItem)
Next
The ToArray method is quick way to create an array from an IEnumerable(Of T) and Cast(Of T) creates an IEnumerable(Of T) from an IEnumerable. In this case, as both the source and the target don't care about the specific type, you can just use Object.
I think you can use AddRange and Clear methods
This exemple below is in c#
https://dotnetfiddle.net/USSfte
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
public class Program
{
private static List<String> _data = new List<String>();
private static void GenerateFakeData(){
_data.AddRange(Enumerable.Range(1,100).Select((e) => String.Format("fake_{0}",e)));
}
public static void Main()
{
GenerateFakeData();
List<string> GroupList= new List<string>();
Console.WriteLine("Before\t\tGroupList.Count:{0}\t_data.Count:{1}",GroupList.Count(),_data.Count());
GroupList = new List<String>();
var FullList = SelectedItems();
/*AddRange*/
GroupList.AddRange(FullList);
/*Clear*/
FullList.Clear();
Console.WriteLine("After\t\tGroupList.Count:{0}\t_data.Count:{1}",GroupList.Count(),_data.Count());
}
public static IList<String> SelectedItems(){
return _data;
}
}
I'm trying to pass a VB.NET List(Of String) collection to a [managed] C++ class [constructor) but am getting an error
Error BC30657 'New' has a return type that is not supported or parameter types that are not supported.
The receiving C++ class is expecting a List parameter which I thought was the C++ equivalent - but clearly it isn't.
What am I doing wrong?
Any recommendations for reading materials for CLI/Non-CLI considerations/how-tos/gotchas?
VB.NET:
Dim myStrList As List(Of String) = New List(Of String)
'<snip> populate list
Dim myObj As MyManagedClass = New MyManagedClass(myStrList)
'ERROR: argument not recognized
C++/CLI:
public ref class MyManagedClass
{
private:
//stuff
public:
MyManagedClass(List<String^> myStringListIn);
}
Apologies if the question isn't worded correctly in terms of terminology. This type of thing is fairly new to me.
I am trying to convert the following ASP.Net C# code to VB.Net:
context.Authentication.SignIn(new AuthenticationProperties
{
Dictionary = {
{ "foo", "bar" }
}
}, new ClaimsIdentity());
The Telerik code converter throws this VB.Net back, but it doesn't compile:
context.Authentication.SignIn(New AuthenticationProperties() With {
.Dictionary = {{"foo", "bar"}}
}, New ClaimsIdentity())
BC30526 Property 'Dictionary' is 'ReadOnly'
So I rewrote it, which does work:
context.Authentication.SignIn(
New AuthenticationProperties(
New Dictionary(Of String, String) From {{"foo", "bar"}}),
New ClaimsIdentity())
While I'm happy with that, for my own understanding I was wondering if VB.Net supports any way to initialize that dictionary without explicity declaring as Dictionary(Of String, String)? Like a lazy inference, of sorts?
Something like...
context.Authentication.SignIn(
New AuthenticationProperties(
New() From {{"foo", "bar"}}),
New ClaimsIdentity())
I am using YamlDotNet library to serialize some objects in Yaml. I've met some problems with the serialization of Guid properties.
Serialization of Guid properties generates empty brackets ( ex: {} )
See code below
Dim l As New List(Of Person)
l.Add(New Person() With {.Firstname = "MyFirstName", .Lastname = "MyLastName", .Id = Guid.NewGuid()})
Using sw As New StreamWriter("output.yaml", False)
Dim serializer = New Serializer()
serializer.Serialize(sw, l)
End Using
this code will output :
- Id: {}
Firstname: MyFirstName
Lastname: MyLastName
With the class:
Public Class Person
Public Property Id As Guid
Public Property Frstname As String
Public Property Lastname As String
End Class
Am I missing something or is this an issue of the library ?
You can define a custom converter to use when you need to customize the serialization of a type. The converter needs to implement IYamlTypeConverter, and be registered on the Serializer or Deserializer. Here is an example of such a converter:
Public Class GuidConverter
Implements IYamlTypeConverter
Public Function Accepts(type As Type) As Boolean Implements IYamlTypeConverter.Accepts
Return type = GetType(Guid)
End Function
Public Function ReadYaml(parser As IParser, type As Type) As Object Implements IYamlTypeConverter.ReadYaml
Dim reader = New EventReader(parser)
Dim scalar = reader.Expect(Of Scalar)()
Return Guid.Parse(scalar.Value)
End Function
Public Sub WriteYaml(emitter As IEmitter, value As Object, type As Type) Implements IYamlTypeConverter.WriteYaml
emitter.Emit(New Scalar(value.ToString()))
End Sub
End Class
The usage is quite simple:
Dim serializer = New Serializer()
serializer.RegisterTypeConverter(New GuidConverter())
serializer.Serialize(Console.Out, New With {.id = Guid.NewGuid()})
You can see a fully working example here.
If I have the following class and declaration:
Public Class objLocation
Public SysLocationId As String
Public NameFull As String
Public LatRaw As String
Public LongRaw As String
Public Active As Integer
End Class
dim lLocation as new objLocation
I can access each variable thus lLocation.SysLocationId, etc. Is there an alternate way, so I can access each variable by index, so something like lLocation(0), lLocation(1), etc., which gives me the flexibility to compare to classes of the same type via a for next loop, or against other sources, like a datatable.
If your goal is comparison, usually what you'll do is implement the IComparable interface or overload the >, < operators (if an ordering is needed) or just the = operator (if equivalence is needed).
You just write one function in one location and invoke that function whenever you need to do your comparison. The same goes for comparing to objects stored in a database. Where you put these functions depends on your application architecture, but for the object-object comparison you can have it as part of the objLocation class itself.
There is no built-in langauge support for this. However you can simulate this by creating a default indexer property on the class
Public Class objLocation
...
Default Public ReadOnly Property Indexer(ByVal index As Integer)
Get
Select Case index
Case 0
Return SysLocationId
Case 1
Return NameFull
Case 2
Return LatRaw
Case 3
Return LongRaw
Case 4
Return Active
Case Else
Throw New ArgumentException
End Select
End Get
End Property
Then you can use it as follows
Dim x As objLocation = GetObjLocation
Dim latRaw = x(2)
No, you can not do this outright.
You have to use reflection to get the properties, but you have to be aware that there is no guarantee on the order of the properties returned (which is important if you want to index them numerically).
Because of that, you will have to keep the sort order consistent when working with the properties (and indexes).
Are you looking for a List:
Dim LocationList As List<objLocation>;
For Each loc As objLocation In LocationList
loc.whatever
Next
or to use the index:
For i = 0 To LocationList.Length - 1
LocationList(i).whatever
Next
sorry, if the VB syntax isn't right...I've been doing C# lately and no VB
You can do that as follows. It is C# and something is a bit different with using indexers in VB, but you should absolutly be able to get it working in VB.
public class ObjLocation
{
private String[] Properties = new String[5];
public const Int32 IndexSysLocationId = 0;
public const Int32 IndexNameFull = 1;
public const Int32 IndexLatRaw = 2;
public const Int32 IndexLongRaw = 3;
public const Int32 IndexActive = 4;
// Repeat this for all properties
public String SysLocationId
{
get { return this.Properties[ObjLocation.IndexSysLocationId]; }
set { this.Properties[ObjLocation.IndexSysLocationId] = value; }
}
public String this[Int32 index]
{
get { return this.Properties[index]; }
set { this.Properties[index] = value; }
}
}
Now you have the object with the properties as before, but stored in an array and you can also access them through an indexer.
This method I implemented in a public structure to return an array of string variables stored in a structure:
Public Shared Function returnArrayValues() As ArrayList
Dim arrayOutput As New ArrayList()
Dim objInstance As New LibertyPIMVaultDefaultCategories()
Dim t As Type = objInstance.GetType()
Dim arrayfinfo() As System.Reflection.FieldInfo = t.GetFields()
For Each finfo As System.Reflection.FieldInfo In arrayfinfo
Dim str As String = finfo.GetValue(objInstance)
arrayOutput.Add(str)
Next
Return arrayOutput
End Function
Put it inside the structure or a class. Maybe this sample code helps.