步行者

--勿在浮沙筑高台
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

动态创建DataGrid模板列

Posted on 2006-05-22 21:10  Niels  阅读(1055)  评论(0编辑  收藏  举报

DataGrid是ASP.NET开发中最常用的控件之一,我们知道,DataGrid中的列包括绑定列,按钮列,超级连接列,模板列等类型,模板列当然是最复杂也最灵活的一种了。在一些项目中,我们需要在DataGrid中显示的列在开发阶段并不能确定,而将其留到了运行时。比如,我们要在DataGrid中显示一张工资表,而各个公司的工资项目并不相同,为适合各不同公司的需要,我们要让用户可以自定义工资项目,这时我们就需要动态创建列。下面的代码演示如何动态生成各种列。
一、绑定列(BoundColumn)

二、按钮列(ButtonColumn)

三、超级连接列(HyperLinkColumn)

四、模板列(TemplateColumn)

 1/// <summary>
 2    /// 类 名 称:DataGridTextBoxTemplate
 3    /// 内容摘要:文本框模板类
 4    /// </summary>

 5    public class DataGridTextBoxTemplate : ITemplate
 6    
 7        // 数据列名
 8        private string fieldName;
 9        // 控件ID
10        private string ctrlID;
11
12        /// <summary>
13        /// 构造方法
14        /// </summary>
15        /// <param name="strCtrlID">控件ID</param>
16        /// <param name="strFieldName">数据列名</param>

17        public DataGridTextBoxTemplate(string strCtrlID, string strFieldName)
18        {
19            fieldName = strFieldName;
20            ctrlID = strCtrlID;
21        }

22           
23        /// <summary>
24        /// 实现ITemplate的InstantiateIn方法
25        /// </summary>
26        /// <param name="container">控件容器</param>

27        public void InstantiateIn(System.Web.UI.Control container)
28        {
29            TextBox tb = new TextBox();
30            tb.ID = ctrlID;
31            tb.Width = Unit.Percentage(100);
32            //tb.Text = "";
33            tb.DataBinding += new EventHandler(TextBoxTemplate_DataBinding);
34            container.Controls.Add(tb);
35        }

36            
37        /// <summary>
38        /// 绑定事件处理
39        /// </summary>
40        /// <param name="sender"></param>
41        /// <param name="e"></param>

42        private void TextBoxTemplate_DataBinding(object sender, System.EventArgs e)
43        {
44            TextBox tb;
45            tb = (TextBox)sender;
46            DataGridItem container = (DataGridItem) tb.NamingContainer;
47            tb.Text += DataBinder.Eval(container.DataItem, fieldName);
48            //tb.Text += "</TD></TR>";
49        }

50    }

我们很快发现,这个DataGridTextBoxTemplate类只能适用于创建内部存放TextBox的模板列,如果按照这样的方式,我们需要创建一个CheckBox列就需要创建一个DataGridCheckBoxTemplate,需要创建一个DropDownList列就需要创建一个DataGridDropDownListTemplate类,这样的话,有多少控件就需要多少个模板类,显然,这样的类不具备通用性。

/// <summary>
    
/// 类 名 称:DataGridTemplate
    
/// 内容摘要:通用模板类
    
/// </summary>

    public class DataGridTemplate : ITemplate
    
{
        
// 数据列名
        private string fieldName;
      
        
// 控件值属性
        private PropertyInfo valueProperty;

        
// 控件
        private Control oCtrl;

        
/// <summary>
        
/// 构造方法
        
/// </summary>
        
/// <param name="oControl">源控件</param>
        
/// <param name="ValueName">控件值属性的名称</param>
        
/// <param name="strFieldName">数据列名</param>

        public DataGridTemplate(Control oControl, string ValueName, string strFieldName)
        
{
            Type oType 
= oControl.GetType();
            
//PropertyInfo oPropertyInfo = oType.GetProperty(ValueName);
            valueProperty = oType.GetProperty(ValueName);
            oCtrl         
= oControl;
            fieldName     
= strFieldName;          
        }

           
        
/// <summary>
        
/// 实现ITemplate的InstantiateIn方法
        
/// </summary>
        
/// <param name="container">控件容器</param>

        public void InstantiateIn(System.Web.UI.Control container)
        
{
            Control tmpCtrl 
=  ControlClone(oCtrl);  
            tmpCtrl.DataBinding 
+= new EventHandler(ControlTemplate_DataBinding);
            container.Controls.Add(tmpCtrl);
        }

            
        
/// <summary>
        
/// 绑定事件处理
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private void ControlTemplate_DataBinding(object sender, System.EventArgs e)
        
{
            Control tmpCtrl;
            tmpCtrl 
= (Control)sender;          
            DataGridItem container 
= (DataGridItem) tmpCtrl.NamingContainer; 
            
try
            
{
                
string s = valueProperty.GetValue(tmpCtrl, null).ToString();
                s 
+= DataBinder.Eval(container.DataItem, fieldName);
                valueProperty.SetValue(tmpCtrl , s ,
null);                
            }

            
catch
            
{
            }

        }


        
/// <summary>
        
/// 复制控件
        
/// </summary>
        
/// <param name="oSource">源控件</param>
        
/// <returns></returns>

        private Control ControlClone(Control oSource)
        
{    
            
//创建复制品
            Control oTarget = (Control)System.Activator.CreateInstance( oSource.GetType() );
            
            
//检查控件是否列表控件
            ListControl oListControl = oSource as ListControl ;
            
if (oListControl != null// 是列表控件
            {
                
foreach (ListItem oItem in oListControl.Items) // 复制列表项
                {
                    ((ListControl)oTarget).Items.Add(
new ListItem(oItem.Text , oItem.Value));
                }

            }

                
            
//将源对象的属性复制给复制品
            Type oType = oSource.GetType() ;
            
// 复制控件属性
            foreach (PropertyInfo oProperty in oType.GetProperties(BindingFlags.Instance| BindingFlags.Public ))
            
{
                
try
                
{
                    
object oData = oProperty.GetValue(oSource, null);
                  
                    oProperty.SetValue(oTarget , oData ,
null);
                }

                
catch{}
            }

            

            
return oTarget;
        }

    }