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 = (0.5 + rv).ToString(),
                        State = index % 2 == 0 ? 1 : 0,
                        MeterId = tag.F_METER_ID,
                        MeterName = tag.F_METER_NAME,
                        ParaId = para.Id
                    };
                    if (para.Id == "10")
                    {
                        o.IsAlarm = false;
                        o.ParaId = string.Empty;
                        o.State = 0;
                        o.Value = string.Empty;
                    }
                    var temp = objs.FirstOrDefault(i => i.MeterName.Equals(o.MeterName) && i.ParaId == o.ParaId);
                    if (temp != null)
                    {
                        temp.IsAlarm = o.IsAlarm;
                        temp.State = o.State;
                        temp.Value = o.Value;
                    }
                    else
                        objs.Add(o);
                }
            }
            //CommHelper.GetSource(Model.Tags, objs, ref this.dataGrid2);
            CommHelper.BindData(Model.Tags, objs, ref this.dataGrid2);
            index++;
        }


        /// <summary>
        /// 
        /// </summary>
        void init()
        {
            Model = new Md();
            Model.Tags = new List<T_METER>();
            Model.Eles = new List<Param>();
            for (int i = 0; i < 1; i++)
            {
                var temp = new T_METER
                {
                    F_BUILD_ID = "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 DynamicColumn
11     {
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 list
112                      group p by new { p.F_BUILD_ID, p.F_METER_ID, p.F_METER_NAME } into gg
113                      select gg.Key;
114             var ramd = new System.Random();
115             foreach (var m in ms)
116             {
117                 var column = new DynamicColumn
118                 {
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                         else
140                             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                     else
143                         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                 else
178                     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                 else
222                     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 = false;
 21             foreach (IDictionary currentDict in list)
 22             {
 23                 hasData = 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 == 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

五,显示效果

原文地址:https://www.cnblogs.com/mybluesky99/p/3939691.html