zoukankan      html  css  js  c++  java
  • WPF中动态创建DataTemplate

    众所周知,在WPF中,我们可以使用DataTemplate灵活地设计UI来呈现绑定的数据,对于不同数据,我们还可以使用DataTemplateSelector选择不同的DataTemplate。但是有时候,这还不能满足需求。这又要说到我正在开发的服装DRP,这并非打广告,而是我阐述的知识点都是在实际项目中碰到的,而且通过项目也好说明问题。

    系统中有个报表叫下级订单分布,列出下级机构的订单量,如图:

    其中订单量相关的单元格中的数字表示的含义:黑色数字表示剩余订单量,红色上标数字表示总订单量-已发货量。毫无疑问,这需要DataTemplate来实现。问题是下级机构的数量是不定的,即GridView绑定的数据列数是不一定的,几个到几百个都有可能(DataTemplateSelector就用不着考虑了),因此我们不能用实体类集合作为绑定数据源(动态增加属性,虽说C#4.0的动态特性大大增强了,但毕竟不是真正的动态语言,使用起来颇为不便,效率还挺低),而只能用DataTable/DataView,并且要动态地指定每个订单列的DataTemplate。假如使用实体类,那么订单列可以绑定到某个复杂属性(包含剩余订单量、总订单量、已发货量),这样DataTemplate只要在xaml中定义一次就可以了。但是既然使用的是DataTable,而DataTable假如从数据库获取的话,它的每一列的数据类型一般都是基本类型(复杂类型没试过,目测DataColumn只支持基础类型(错误,DataColumn支持复杂类型,且前端XAML绑定可写成“ColumnName.PropertyName”)),动态创建DataTemplate就必不可少了。

    关于动态创建DataTemplate,我参考了WPF中使用C#程序代码创建DataTemplate数据模版的方法。代码如下: 

     1 private void btnSearch_Click(object sender, RoutedEventArgs e)
     2 {
     3     while (gv.Columns.Count > 5)
     4         gv.Columns.RemoveAt(5);
     5     var data = _dataContext.GetSubordinateOrderDistribution();
     6     bool showAll = rbAllOrder.IsChecked.Value;
     7     if (!showAll)
     8         data.RemoveAll(o => o.QuaDelivered == o.Quantity);
     9     DataTable table = new DataTable();
    10     table.Columns.Add(new DataColumn("ProductCode", typeof(string)));
    11     table.Columns.Add(new DataColumn("BrandCode", typeof(string)));
    12     table.Columns.Add(new DataColumn("StyleCode", typeof(string)));
    13     table.Columns.Add(new DataColumn("ColorCode", typeof(string)));
    14     table.Columns.Add(new DataColumn("SizeName", typeof(string)));
    15     var onames = data.Select(o => o.OrganizationName).Distinct().ToList();
    16     onames.Add("合计");
    17     foreach (var on in onames)
    18     {
    19         table.Columns.Add(new DataColumn(on, typeof(int)));
    20         table.Columns.Add(new DataColumn("delivered" + on, typeof(int)));
    21         table.Columns.Add(new DataColumn("all" + on, typeof(int)));
    22         //gv.Columns.Add(new GridViewDataColumn() { Header = on, Name = on, DataMemberBinding = new Binding(on) });
    23         var col = new GridViewDataColumn() { Header = on, Name = on, DataMemberBinding = new Binding(on) };
    24         //内存中动态生成一个XAML,描述了一个DataTemplate
    25         XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
    26         XElement xGrid = new XElement(ns + "Grid", new XElement(ns + "Grid.ColumnDefinitions", new XElement(ns + "ColumnDefinition", new XAttribute("Width", "Auto")), new XElement(ns + "ColumnDefinition", new XAttribute("Width", "Auto"))));
    27         xGrid.Add(new XElement(ns + "TextBlock", new XAttribute("Text", "{Binding Path=" + on + "}"), new XAttribute("Margin", "0 0 5 0")));
    28         if (showAll)
    29         {
    30             xGrid.Add(
    31                 new XElement(ns + "TextBlock", new XAttribute("Foreground", "Red"), new XAttribute("Text", "{Binding Path=" + "delivered" + on + "}"), new XAttribute("FontSize", "8"), new XAttribute("Grid.Column", "1")));
    32         }
    33         else
    34         {
    35             xGrid.Add(
    36                 new XElement(ns + "TextBlock", new XAttribute("Foreground", "Red"), new XAttribute("FontSize", "8"), new XAttribute("Grid.Column", "1"),
    37                 new XElement(ns + "TextBlock", new XAttribute("Text", "{Binding Path=" + "all" + on + "}")),
    38                 new XElement(ns + "TextBlock", new XAttribute("Text", "-")),
    39                 new XElement(ns + "TextBlock", new XAttribute("Text", "{Binding Path=" + "delivered" + on + "}"))));
    40         }
    41         XElement xDataTemplate = new XElement(ns + "DataTemplate", new XAttribute("xmlns", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"));
    42         xDataTemplate.Add(xGrid);
    43         XmlReader xr = xDataTemplate.CreateReader();
    44         DataTemplate dataTemplate = XamlReader.Load(xr) as DataTemplate;
    45         col.CellTemplate = dataTemplate;
    46         gv.Columns.Add(col);
    47     }
    48     var ps = data.OrderBy(o => o.ProductCode).Select(o => o.ProductID).Distinct();
    49     foreach (var p in ps)
    50     {
    51         var d = data.First(o => o.ProductID == p);
    52         DataRow row = table.NewRow();
    53         table.Rows.Add(row);
    54         row["ProductCode"] = d.ProductCode;
    55         row["BrandCode"] = d.BrandCode;
    56         row["StyleCode"] = d.StyleCode;
    57         row["ColorCode"] = d.ColorCode;
    58         row["SizeName"] = d.SizeName;
    59         foreach (var on in onames)
    60         {
    61             if (on == "合计")
    62             {
    63                 var totalData = data.Where(o => o.ProductID == p);
    64                 var quantity = totalData.Sum(o => o.Quantity);
    65                 var quaDelivered = totalData.Sum(o => o.QuaDelivered);
    66                 row[on] = showAll ? quantity : (quantity - quaDelivered);
    67                 row["all" + on] = quantity;
    68                 row["delivered" + on] = quaDelivered;
    69                 continue;
    70             }
    71             d = data.Find(o => o.ProductID == p && o.OrganizationName == on);
    72             if (d != null)
    73             {
    74                 row[on] = showAll ? d.Quantity : (d.Quantity - d.QuaDelivered);
    75                 row["all" + on] = d.Quantity;
    76                 row["delivered" + on] = d.QuaDelivered;
    77             }
    78         }
    79     }
    80     gv.ItemsSource = table.DefaultView;
    81 }

     注意最后ItemsSource设置成DefaultView,如果直接用DataTable那么CellTemplate的Binding就有问题,无法绑定,不知何故。另外XElement xDataTemplate = new XElement(ns + "DataTemplate", new XAttribute("xmlns", http://schemas.microsoft.com/winfx/2006/xaml/presentation)); ns和xmlns属性声明都不能忽略,否则会报错。

    转载请注明本文出处:http://www.cnblogs.com/newton/archive/2012/12/13/2816753.html

  • 相关阅读:
    faster with MyISAM tables than with InnoDB or NDB tables
    w-BIG TABLE 1-toSMALLtable @-toMEMORY
    Indexing and Hashing
    MEMORY Storage Engine MEMORY Tables TEMPORARY TABLE max_heap_table_size
    controlling the variance of request response times and not just worrying about maximizing queries per second
    Variance
    Population Mean
    12.162s 1805.867s
    situations where MyISAM will be faster than InnoDB
    1920.154s 0.309s 30817
  • 原文地址:https://www.cnblogs.com/newton/p/2816753.html
Copyright © 2011-2022 走看看