Hi all.
I'm currently busy with Silverlight 2, and i wanted to fill a grid with just some info. Now silverlight 2 don't support a dataset, so i searched for an another option.
I found it on this website, but in C#:
http://blog.bodurov.com/blog/Post.aspx?postID=27Now i was converting the code to VB.NET, but at some point i don't get it. Here's the code:
DataSourceCreator.cs: (i have this already in .NET)
CODE
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.Text.RegularExpressions;
namespace DataSetSilverlight
{
public static class DataSourceCreator
{
private static readonly Regex PropertNameRegex =
new Regex(@"^[A-Za-z]+[A-Za-z1-9_]*$", RegexOptions.Singleline);
public static IEnumerable ToDataSource(this IEnumerable<IDictionary> list)
{
IDictionary firstDict = null;
bool hasData = false;
foreach (IDictionary currentDict in list)
{
hasData = true;
firstDict = currentDict;
break;
}
if (!hasData)
{
return new object[] { };
}
if (firstDict == null)
{
throw new ArgumentException("IDictionary entry cannot be null");
}
Type objectType = null;
TypeBuilder tb = GetTypeBuilder(list.GetHashCode());
ConstructorBuilder constructor =
tb.DefineDefaultConstructor(
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.RTSpecialName);
foreach (DictionaryEntry pair in firstDict)
{
if (PropertNameRegex.IsMatch(Convert.ToString(pair.Key), 0))
{
CreateProperty(tb,
Convert.ToString(pair.Key),
pair.Value == null ?
typeof(object) :
pair.Value.GetType());
}
else
{
throw new ArgumentException(
@"Each key of IDictionary must be
alphanumeric and start with character.");
}
}
objectType = tb.CreateType();
return GenerateEnumerable(objectType, list, firstDict);
}
private static IEnumerable GenerateEnumerable(
Type objectType, IEnumerable<IDictionary> list, IDictionary firstDict)
{
var listType = typeof(List<>).MakeGenericType(new[] { objectType });
var listOfCustom = Activator.CreateInstance(listType);
foreach (var currentDict in list)
{
if (currentDict == null)
{
throw new ArgumentException("IDictionary entry cannot be null");
}
var row = Activator.CreateInstance(objectType);
foreach (DictionaryEntry pair in firstDict)
{
if (currentDict.Contains(pair.Key))
{
PropertyInfo property =
objectType.GetProperty(Convert.ToString(pair.Key));
property.SetValue(
row,
Convert.ChangeType(
currentDict[pair.Key],
property.PropertyType,
null),
null);
}
}
listType.GetMethod("Add").Invoke(listOfCustom, new[] { row });
}
return listOfCustom as IEnumerable;
}
private static TypeBuilder GetTypeBuilder(int code)
{
AssemblyName an = new AssemblyName("TempAssembly" + code);
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType("TempType" + code
, TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout
, typeof(object));
return tb;
}
private static void CreateProperty(
TypeBuilder tb, string propertyName, Type propertyType)
{
FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName,
propertyType,
FieldAttributes.Private);
PropertyBuilder propertyBuilder =
tb.DefineProperty(
propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr =
tb.DefineMethod("get_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
propertyType, Type.EmptyTypes);
ILGenerator getIL = getPropMthdBldr.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, fieldBuilder);
getIL.Emit(OpCodes.Ret);
MethodBuilder setPropMthdBldr =
tb.DefineMethod("set_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
null, new Type[] { propertyType });
ILGenerator setIL = setPropMthdBldr.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, fieldBuilder);
setIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
}
}
Page.xaml.cs: (almost converted to vb)
CODE
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace DataSetSilverlight
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.theGrid.Columns.Add(
new DataGridTextColumn
{
Header = "ID:",
DisplayMemberBinding = new Binding("ID")
});
this.theGrid.Columns.Add(
new DataGridTextColumn
{
Header = "Name:",
DisplayMemberBinding = new Binding("Name")
});
this.theGrid.Columns.Add(
new DataGridTextColumn
{
Header = "Index:",
DisplayMemberBinding = new Binding("Index")
});
this.theGrid.Columns.Add(
new DataGridCheckBoxColumn
{
Header = "IsEven:",
DisplayMemberBinding = new Binding("IsEven")
});
this.theGrid.ItemsSource = GenerateData().ToDataSource();
}
public IEnumerable<IDictionary> GenerateData()
{
for (var i = 0; i < 15; i++)
{
var dict = new Dictionary<string, object>();
dict.Add("ID", Guid.NewGuid());
dict.Add("Name", "Name_" + i);
dict.Add("Index", i);
dict.Add("IsEven", i % 2 == 0);
yield return dict;
}
}
}
}
Now the point where i'm stuck is here at the end of Page.xaml.cs:
CODE
this.theGrid.ItemsSource = GenerateData().ToDataSource();
}
public IEnumerable<IDictionary> GenerateData()
{
for (var i = 0; i < 15; i++)
{
var dict = new Dictionary<string, object>();
dict.Add("ID", Guid.NewGuid());
dict.Add("Name", "Name_" + i);
dict.Add("Index", i);
dict.Add("IsEven", i % 2 == 0);
yield return dict;
}
}
It says 'yield return dict;'. I searched google but it seems VB.NET doesn't have 'yield'.... somebody knows a workaround which will work in this code?
Thank you.