datagrid 绑定动态列

如题, 许多时候我们渴望绑定一个不确定的列到datagrid,

如果你真想这样那么10分钟后你将实现,

缺点是你不可能在datagrid的一行中得到一个完整的类了.

她借助了一个国外的源码类,DataGridDataSource.cs

--------------------------------------------------------------------------

代码:

  
    
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Controls;
using DataGridDataSource;

namespace GridTestSilverlight
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this .TheGrid.ItemsSource = GenerateData( " 这里传入数据 " ).ToDataSource();
}
public IEnumerable < IDictionary > GenerateData( string xml)
{
// 注意此处的for循环,只是为了模拟数据格式,
// 卑微的我只是提供了一种绑定多列的方式,
// 伟大而牛B的您可以根据自己需求满足这种格式,
for ( int j = 200 ; j < 215 ;j ++ )
{
var dict
= new Dictionary < object , object > ();
for (var i = 1 ; i <= 4 ; i ++ )
{
dict[
" 当前列 " + i] = " --- " + j ;
}
yield return dict;
}

}
}
}
/*
我自己实际工程中用到的.
* 数据格式为
* <Temp>
* <时间>2011-3-14 10:21:52</时间>
* <时间>2011-3-16 10:21:52</时间>
* <时间>2011-3-17 10:21:52</时间>
* <时间>2011-3-18 10:21:52</时间>
* </Temp>
* <Temp>
* <时间>2011-3-19 10:21:52</时间>
* <时间>2011-3-21 10:21:52</时间>
* <时间>2011-3-31 10:21:52</时间>
* <时间>2011-3-22 10:21:52</时间>
* </Temp>
* private IEnumerable<IDictionary> GenerateData(XDocument xml)
{
var element = xml.Descendants("Temp");

foreach (XElement item in element)
{
var dict = new Dictionary<object, object>();
var nodes = item.Elements();
foreach (XElement node in nodes)
{
dict[node.Name] = node.Value;
}
yield return dict;
}
}
*
*/

DataGridDataSource.cs  类

对于此文件, 类中注释部分为源码,注释下方是我添加的,不难看出是为了能够让DataGrid的表头出现中文.

自此皆大欢喜.  我用到了我想用的.

  
    
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;

namespace DataGridDataSource
{
public static class DataSourceCreator
{
// private static readonly Regex PropertNameRegex =
// new Regex(@"^[A-Za-z]+[A-Za-z0-9_]*$", RegexOptions.Singleline);
private static readonly Regex PropertNameRegex =
new Regex( @" ^[\u4e00-\u9fa5]+$ " , RegexOptions.Singleline);

private static readonly Dictionary < string , Type > _typeBySigniture =
new Dictionary < string , Type > ();


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 " );
}

string typeSigniture = GetTypeSigniture(firstDict);

Type objectType
= GetTypeByTypeSigniture(typeSigniture);

if (objectType == null )
{
TypeBuilder tb
= GetTypeBuilder(typeSigniture);

ConstructorBuilder constructor
=
tb.DefineDefaultConstructor(
MethodAttributes.Public
|
MethodAttributes.SpecialName
|
MethodAttributes.RTSpecialName);


foreach (DictionaryEntry pair in firstDict)
{
// if (PropertNameRegex.IsMatch(Convert.ToString(pair.Key), 0))
if ( true )
{
CreateProperty(tb,
Convert.ToString(pair.Key),
GetValueType(pair.Value));
}
else
{
throw new ArgumentException(
@" Each key of IDictionary must be
alphanumeric and start with character.
" );
}
}
objectType
= tb.CreateType();

_typeBySigniture.Add(typeSigniture, objectType);
}

return GenerateEnumerable(objectType, list, firstDict);
}

private static Type GetTypeByTypeSigniture( string typeSigniture)
{
Type type;
return _typeBySigniture.TryGetValue(typeSigniture, out type) ? type : null ;
}

private static Type GetValueType( object value)
{
return value == null ? typeof ( object ) : value.GetType();
}

private static string GetTypeSigniture(IDictionary firstDict)
{
StringBuilder sb
= new StringBuilder();
foreach (DictionaryEntry pair in firstDict)
{
sb.AppendFormat(
" _{0}_{1} " , pair.Key, GetValueType(pair.Value));
}
return sb.ToString().GetHashCode().ToString().Replace( " - " , " Minus " );
}

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));
var value
= currentDict[pair.Key];
try
{
if (value != null && value.GetType() != property.PropertyType && ! property.PropertyType.IsGenericType)
value
= Convert.ChangeType(
currentDict[pair.Key],
property.PropertyType,
null );
}
catch
{
}

property.SetValue(
row,
value,
null );
}
}
listType.GetMethod(
" Add " ).Invoke(listOfCustom, new [] { row });
}
return listOfCustom as IEnumerable;
}

private static TypeBuilder GetTypeBuilder( string typeSigniture)
{
AssemblyName an
= new AssemblyName( " TempAssembly " + typeSigniture);
AssemblyBuilder assemblyBuilder
=
AppDomain.CurrentDomain.DefineDynamicAssembly(
an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder
= assemblyBuilder.DefineDynamicModule( " MainModule " );

TypeBuilder tb
= moduleBuilder.DefineType( " TempType " + typeSigniture
, 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)
{
if (propertyType.IsValueType && ! propertyType.IsGenericType)
{
propertyType
= typeof (Nullable <> ).MakeGenericType( new [] { 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);
}
}



}

你可能感兴趣的:(datagrid)