首页 > 代码库 > Silverlight日记:动态生成DataGrid、行列装换、动态加载控件

Silverlight日记:动态生成DataGrid、行列装换、动态加载控件

本文主要针对使用DataGrid动态绑定数据对象,并实现行列转换效果。

一,前台绑定

<sdk:DataGrid x:Name="dataGrid2" Style="{StaticResource ResourceKey=safeDataGrid2}" />
using System;using System.Collections;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Net;using System.Reflection;using System.Reflection.Emit;using System.Text;using System.Text.RegularExpressions;using System.Threading;using System.Windows;using System.Windows.Controls;using System.Windows.Controls.Primitives;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Markup;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;using System.Windows.Threading;using Test.Util;namespace Test{    public partial class MainPage : UserControl    {        public Md Model = null;        private DispatcherTimer timer;        int index = 0;        /// <summary>        ///         /// </summary>        public ObservableCollection<Obj> objs = new ObservableCollection<Obj>();        public MainPage()        {            InitializeComponent();            init();            timer = new DispatcherTimer();            timer.Interval = new TimeSpan(0, 0, 8);            timer.Tick += timer_Tick;            timer.Start();        }        /// <summary>        ///         /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        void timer_Tick(object sender, EventArgs e)        {            var ramd = new Random();            foreach (var tag in Model.Tags)            {                foreach (var para in Consts.Params)                {                    var rv = index % 2 == 0 ? ramd.Next(2, 10) : ramd.Next(1, 5);                    var o = new Obj                    {                        IsAlarm = false,                        Value = http://www.mamicode.com/(0.5 + rv).ToString(),"10")                    {                        o.IsAlarm = false;                        o.ParaId = string.Empty;                        o.State = 0;                        o.Value = http://www.mamicode.com/string.Empty;"440300B059",                    F_METER_ID = string.Format("TAG_{0}", i),                    F_METER_NAME = string.Format("CM-{0}", i)                };                if (i == 0)                    temp.F_EQT_TYPE = "D";                else if (i == 1)                    temp.F_EQT_TYPE = "C";                else if (i == 2)                    temp.F_EQT_TYPE = "E";                else                    temp.F_EQT_TYPE = "A";                Model.Tags.Add(temp);            }            this.dataGrid1.ItemsSource = Consts.Params;            CommHelper.CreateDataGrid(Model.Tags, ref this.dataGrid2);        }    }    /// <summary>    ///     /// </summary>    public class Md    {        /// <summary>        /// 参数集合        /// </summary>        public List<Param> Eles { get; set; }        /// <summary>        /// 电表集合        /// </summary>        public List<T_METER> Tags { get; set; }    }    /// <summary>    ///     /// </summary>    public class T_METER    {        public string F_BUILD_ID { get; set; }        public string F_METER_ID { get; set; }        public string F_METER_NAME { get; set; }        public string F_EQT_TYPE { get; set; }        public string F_VALUE { get; set; }    }    /// <summary>    /// 参数    /// </summary>    public class Param    {        public string Id { get; set; }        public string Name { get; set; }    }    /// <summary>    /// 绑定数据对象    /// </summary>    public class Obj    {        /// <summary>        /// 对应参数编号        /// </summary>        public string ParaId { get; set; }        public string MeterId { get; set; }        /// <summary>        /// 电表名称        /// </summary>        public string MeterName { get; set; }        /// <summary>        /// 开关状态0-关,1-开        /// </summary>        public int State { get; set; }        /// <summary>        /// OPC读取值        /// </summary>        public string Value { get; set; }        /// <summary>        /// 是否报警        /// </summary>        public bool IsAlarm { get; set; }    }}

  

二,动态列对象

 1 using System.Collections.Generic; 2  3 namespace Test.Util 4 { 5     /* ============================== 6      * Desc:DynamicColumn   7      * Author:hezp 8      * Date:2014/8/14 15:49:17 9      * ==============================*/10     public class DynamicColumn11     {12         /// <summary>13         /// 列名14         /// </summary>15         public string ColumnName { get; set; } 16         /// <summary>17         /// 列对应集合18         /// </summary>19         public List<string> Values { get; set; }20     }21 }

三,DataGrid动态生成类

  1 using System;  2 using System.Linq;  3 using System.Collections;  4 using System.Collections.Generic;  5 using System.Net;  6 using System.Text;  7 using System.Windows;  8 using System.Windows.Controls;  9 using System.Windows.Documents; 10 using System.Windows.Ink; 11 using System.Windows.Input; 12 using System.Windows.Markup; 13 using System.Windows.Media; 14 using System.Windows.Media.Animation; 15 using System.Windows.Shapes; 16 using System.Text.RegularExpressions; 17 using System.Collections.ObjectModel; 18  19 namespace Test.Util 20 { 21     /* ============================== 22      * Desc:CommHelper   23      * Author:hezp 24      * Date:2014/8/14 15:58:26 25      * ==============================*/ 26     public class CommHelper 27     { 28         /// <summary> 29         ///  30         /// </summary> 31         /// <param name="columnBindName"></param> 32         /// <param name="columnHeaderName"></param> 33         /// <param name="width"></param> 34         /// <param name="index"></param> 35         /// <returns></returns> 36         private static DataGridTemplateColumn CreateDataGridTextColumn(string columnBindName, string columnHeaderName, T_METER tag) 37         { 38             DataGridTemplateColumn dgColumn = new DataGridTemplateColumn(); 39             dgColumn.Header = columnHeaderName; 40             dgColumn.IsReadOnly = true; 41             var w = 70; 42             if (tag != null) 43             { 44                 if (tag.F_EQT_TYPE.Equals("D")) 45                 { 46                     dgColumn.HeaderStyle = ResourcesWrapper.GetStyle<Style>("safeByqStyle"); 47                     w = 120; 48                 } 49                 else if (tag.F_EQT_TYPE.Equals("B")) 50                 { 51                     dgColumn.HeaderStyle = ResourcesWrapper.GetStyle<Style>("safeSingleDrStyle"); 52                     w = 90; 53                 } 54                 else if (tag.F_EQT_TYPE.Equals("C")) 55                 { 56                     dgColumn.HeaderStyle = ResourcesWrapper.GetStyle<Style>("safeDoubleDrStyle"); 57                     w = 150; 58                 } 59                 else if (tag.F_EQT_TYPE.Equals("E")) 60                 { 61                     dgColumn.HeaderStyle = ResourcesWrapper.GetStyle<Style>("safeHookStyle"); 62                     w = 98; 63                 } 64                 else 65                     dgColumn.HeaderStyle = ResourcesWrapper.GetStyle<Style>("safeMeterStyle"); 66             } 67             else 68                 dgColumn.HeaderStyle = ResourcesWrapper.GetStyle<Style>("safeMeterStyle"); 69  70             dgColumn.CellStyle = ResourcesWrapper.GetStyle<Style>("safeCellStyle"); 71  72             StringBuilder cellTemplate = new StringBuilder(); 73             cellTemplate.Append("<DataTemplate  "); 74             cellTemplate.Append(" xmlns=‘http://schemas.microsoft.com/client/2007‘ "); 75             cellTemplate.Append(" xmlns:x=‘http://schemas.microsoft.com/winfx/2006/xaml‘ "); 76             cellTemplate.Append(" xmlns:c=‘clr-namespace:Test.Controls;assembly=Test.Controls‘ "); 77             cellTemplate.Append(" xmlns:local = ‘Test"); 78             cellTemplate.Append(";assembly=Test‘>"); 79             cellTemplate.Append(string.Format("<c:CustomCell Width=‘{1}‘ Text=‘{{Binding {0}}}‘/>", columnBindName, w)); 80             cellTemplate.Append("</DataTemplate>"); 81             dgColumn.CellTemplate = (DataTemplate)XamlReader.Load(cellTemplate.ToString()); 82             dgColumn.CellTemplate.LoadContent(); 83  84             return dgColumn; 85         } 86  87         /// <summary> 88         ///  89         /// </summary> 90         /// <param name="SourceList"></param> 91         /// <returns></returns> 92         private static IEnumerable<IDictionary> GetEnumerable(List<Dictionary<string, string>> SourceList) 93         { 94             for (int i = 0; i < SourceList.Count; i++) 95             { 96                 var dict = new Dictionary<string, string>(); 97                 dict = SourceList[i]; 98                 yield return dict; 99             }100         }101         /// <summary>102         /// 103         /// </summary>104         /// <param name="list"></param>105         /// <param name="objs"></param>106         /// <returns></returns>107         private static List<DynamicColumn> Grenartor(List<T_METER> list, ObservableCollection<Obj> objs)108         {109             var columns = new List<DynamicColumn>();110             if (null == list) return null;111             var ms = from p in list112                      group p by new { p.F_BUILD_ID, p.F_METER_ID, p.F_METER_NAME } into gg113                      select gg.Key;114             var ramd = new System.Random();115             foreach (var m in ms)116             {117                 var column = new DynamicColumn118                 {119                     ColumnName = string.Format("{0}____{1}", m.F_METER_NAME, 0)//格式:支路名称|开关状态值120                 };121                 if (objs != null)122                 {123                     var obj = objs.FirstOrDefault(i => i.MeterName.Equals(m.F_METER_NAME));124                     if (obj != null)125                         column.ColumnName = string.Format("{0}____{1}", obj.MeterName, obj.State);126                 }127                 column.Values = new List<string>();128                 var count = Consts.Params.Count;129                 for (int i = 0; i < count; i++)130                 {131                     var v = false;//是否显示按钮132                     if (i == count - 1)133                         v = true;134                     if (objs != null)135                     {136                         var temp = objs.FirstOrDefault(j => j.MeterName.Equals(m.F_METER_NAME) && !string.IsNullOrEmpty(j.ParaId) && j.ParaId.Equals(Consts.Params[i].Id));137                         if (temp != null)138                             column.Values.Add(string.Format("{0}____{1}____{2}____{3}____{4}____{5}____{6}", m.F_BUILD_ID, m.F_METER_ID, m.F_METER_NAME, temp.Value, v, temp.IsAlarm, Consts.Params[i].Id));139                         else140                             column.Values.Add(string.Format("{0}____{1}____{2}____{3}____{4}____{5}____{6}", m.F_BUILD_ID, m.F_METER_ID, m.F_METER_NAME, "-", v, false, Consts.Params[i].Id));//格式:建筑编号____支路编号____支路名称____数值____是否是按钮____是否报警  141                     }142                     else143                         column.Values.Add(string.Format("{0}____{1}____{2}____{3}____{4}____{5}____{6}", m.F_BUILD_ID, m.F_METER_ID, m.F_METER_NAME, "-", v, false, Consts.Params[i].Id));144                 }145                 columns.Add(column);146             }147             return columns;148         }149         /// <summary>150         /// 绑定数据151         /// </summary>152         /// <param name="tags"></param>153         /// <param name="objs"></param>154         /// <param name="datagrid"></param>155         public static void BindData(List<T_METER> tags, ObservableCollection<Obj> objs, ref DataGrid datagrid)156         {157             var list = Grenartor(tags, objs);158             var dataSources = new List<Dictionary<string, string>>();159             for (int j = 0; j < 10; j++)160             {161                 var dict = new Dictionary<string, string>();//数据行(Key:列名,Value:列值)162                 list.ForEach(item =>163                 {164                     dict.Add(item.ColumnName.Replace(" ", "_").Replace("-", "_"), item.Values[j]);165                 });166                 dataSources.Add(dict);167             }168             foreach (var item in list)169             {170                 var index = list.IndexOf(item);171                 var arr = Regex.Split(item.ColumnName, "____", RegexOptions.IgnoreCase);172                 var tag = tags.FirstOrDefault(i => i.F_METER_NAME.ToUpper().Equals(arr[0].ToUpper()));173                 var column = CreateDataGridTextColumn(item.ColumnName.Replace(" ", "_").Replace("-", "_"), item.ColumnName, tag);174                 var cl = datagrid.Columns.FirstOrDefault(i => i.Header.ToString().StartsWith(tag.F_METER_NAME));175                 if (cl != null)176                     cl = column;177                 else178                     datagrid.Columns.Add(column);179             }180             datagrid.ItemsSource = GetEnumerable(dataSources).ToDataSource();181         }182 183         public static void GetSource(List<T_METER> tags, ObservableCollection<Obj> objs, ref DataGrid datagrid)184         {185             var list = Grenartor(tags, objs);186             var dataSources = new List<Dictionary<string, string>>();187             for (int j = 0; j < 10; j++)188             {189                 var dict = new Dictionary<string, string>();//数据行(Key:列名,Value:列值)190                 list.ForEach(item =>191                 {192                     dict.Add(item.ColumnName.Replace(" ", "_").Replace("-", "_"), item.Values[j]);193                 });194                 dataSources.Add(dict);195             }            196             datagrid.ItemsSource = GetEnumerable(dataSources).ToDataSource();197         }198 199         public static void CreateDataGrid(List<T_METER> tags, ref DataGrid datagrid)200         {201             var list = Grenartor(tags, null);202             var dataSources = new List<Dictionary<string, string>>();203             for (int j = 0; j < 10; j++)204             {205                 var dict = new Dictionary<string, string>();//数据行(Key:列名,Value:列值)206                 list.ForEach(item =>207                 {208                     dict.Add(item.ColumnName.Replace(" ", "_").Replace("-", "_"), item.Values[j]);209                 });210                 dataSources.Add(dict);211             }212             foreach (var item in list)213             {214                 var index = list.IndexOf(item);215                 var arr = Regex.Split(item.ColumnName, "____", RegexOptions.IgnoreCase);216                 var tag = tags.FirstOrDefault(i => i.F_METER_ID.ToUpper().Equals(arr[0].ToUpper()));217                 var column = CreateDataGridTextColumn(item.ColumnName.Replace(" ", "_").Replace("-", "_"), item.ColumnName, tag);218                 var cl = datagrid.Columns.FirstOrDefault(i => i.Header.ToString().StartsWith(tag.F_METER_NAME));219                 if (cl != null)220                     cl = column;221                 else222                     datagrid.Columns.Add(column);223             }224             datagrid.ItemsSource = GetEnumerable(dataSources).ToDataSource();225         }226     }227 }
View Code

四,数据源构造(实现行列转换)类

  1 using System;  2 using System.Collections;  3 using System.Collections.Generic;  4 using System.Collections.ObjectModel;  5 using System.Reflection;  6 using System.Reflection.Emit;  7   8 namespace Test.Util  9 { 10     /* ============================== 11      * Desc:DataSourceCreator   12      * Author:hezp 13      * Date:2014/8/14 15:51:04 14      * ==============================*/ 15     public static class DataSourceCreator 16     { 17         public static ObservableCollection<object> ToDataSource(this IEnumerable<IDictionary> list) 18         { 19             IDictionary firstDict = null; 20             bool hasData = http://www.mamicode.com/false; 21             foreach (IDictionary currentDict in list) 22             { 23                 hasData = http://www.mamicode.com/true; 24                 firstDict = currentDict; 25                 break; 26             } 27             if (!hasData) 28             { 29                 return new ObservableCollection<object> { }; 30             } 31             if (firstDict == null) 32             { 33                 throw new ArgumentException("IDictionary entry cannot be null"); 34             } 35             Type objectType = null; 36             TypeBuilder tb = GetTypeBuilder(list.GetHashCode()); 37             ConstructorBuilder constructor = 38                         tb.DefineDefaultConstructor( 39                                     MethodAttributes.Public | 40                                     MethodAttributes.SpecialName | 41                                     MethodAttributes.RTSpecialName); 42             foreach (DictionaryEntry pair in firstDict) 43             { 44  45                 CreateProperty(tb, 46                                 Convert.ToString(pair.Key), 47                                 pair.Value =http://www.mamicode.com/= null ? 48                                             typeof(object) : 49                                             pair.Value.GetType()); 50  51             } 52             objectType = tb.CreateType(); 53             return GenerateArray(objectType, list, firstDict); 54         } 55         private static ObservableCollection<object> GenerateArray(Type objectType, IEnumerable<IDictionary> list, IDictionary firstDict) 56         { 57             var itemsSource = new ObservableCollection<object>(); 58             foreach (var currentDict in list) 59             { 60                 object row = Activator.CreateInstance(objectType); 61                 foreach (DictionaryEntry pair in firstDict) 62                 { 63                     if (currentDict.Contains(pair.Key)) 64                     { 65                         PropertyInfo property = 66                             objectType.GetProperty(Convert.ToString(pair.Key)); 67                         property.SetValue( 68                             row, 69                             Convert.ChangeType( 70                                     currentDict[pair.Key], 71                                     property.PropertyType, 72                                     null), 73                             null); 74                     } 75                 } 76                 itemsSource.Add(row); 77             } 78             return itemsSource; 79         } 80         private static TypeBuilder GetTypeBuilder(int code) 81         { 82             AssemblyName an = new AssemblyName("TempAssembly" + code); 83             AssemblyBuilder assemblyBuilder = 84                 AppDomain.CurrentDomain.DefineDynamicAssembly( 85                     an, AssemblyBuilderAccess.Run); 86             ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); 87             TypeBuilder tb = moduleBuilder.DefineType("TempType" + code 88                                 , TypeAttributes.Public | 89                                 TypeAttributes.Class | 90                                 TypeAttributes.AutoClass | 91                                 TypeAttributes.AnsiClass | 92                                 TypeAttributes.BeforeFieldInit | 93                                 TypeAttributes.AutoLayout 94                                 , typeof(object)); 95             return tb; 96         } 97         private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) 98         { 99             FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName,100                                                         propertyType,101                                                         FieldAttributes.Private);102 103             PropertyBuilder propertyBuilder =104                 tb.DefineProperty(105                     propertyName, PropertyAttributes.HasDefault, propertyType, null);106             MethodBuilder getPropMthdBldr =107                 tb.DefineMethod("get_" + propertyName,108                     MethodAttributes.Public |109                     MethodAttributes.SpecialName |110                     MethodAttributes.HideBySig,111                     propertyType, Type.EmptyTypes);112             ILGenerator getIL = getPropMthdBldr.GetILGenerator();113             getIL.Emit(OpCodes.Ldarg_0);114             getIL.Emit(OpCodes.Ldfld, fieldBuilder);115             getIL.Emit(OpCodes.Ret);116             MethodBuilder setPropMthdBldr =117                 tb.DefineMethod("set_" + propertyName,118                   MethodAttributes.Public |119                   MethodAttributes.SpecialName |120                   MethodAttributes.HideBySig,121                   null, new Type[] { propertyType });122             ILGenerator setIL = setPropMthdBldr.GetILGenerator();123             setIL.Emit(OpCodes.Ldarg_0);124             setIL.Emit(OpCodes.Ldarg_1);125             setIL.Emit(OpCodes.Stfld, fieldBuilder);126             setIL.Emit(OpCodes.Ret);127             propertyBuilder.SetGetMethod(getPropMthdBldr);128             propertyBuilder.SetSetMethod(setPropMthdBldr);129         }130     }131 }
View Code

五,显示效果

Silverlight日记:动态生成DataGrid、行列装换、动态加载控件