绝对适合您的DataPropertyGrid!

简介

DataPropertyGrid,正如它的名字,是一个继承于PropertyGrid的扩展控件,它可以浏览和编辑数据。

开发背景

我们以前这样写:

public class myClass
{
   
public myClass(System.Data.DataRow row)
   
{
      myRow 
= row;
      
if(myRow["Name"!= System.DBNull.Value)
      
{
         
this.Name = (string)myRow["Name"];
      }

      
if(myRow["BirthDay"!= System.DBNull.Value)
      
{
         
this.BirthDay = (DateTime)myRow["BirthDay"];
      }

   }


   
private System.Data.DataRow myRow = null;

   
private string    m_name;
   
public string Name
   
{
      
get return m_name; }
      
set 
      

         m_name 
= value; 
         myRow[
"Name"= value;
      }

    }


    
private DateTime    m_birthDay;
    
public DateTime BirthDay
    
{
       
get return m_birthDay; }
       
set 
       

          m_birthDay 
= value; 
          myRow[
"BirthDay"= value;
       }

    }


}




private void Form1_Load(object sender, System.EventArgs e)
{
    myClass obj 
= new myClass(dataRow);
    
this.propertyGrid1.SelectedObject = obj;
}


很不方便。

理解DataPropertyGrid控件 

DataPropertyGrid dynamically creates a class from the columns of the DataRow that passed as parameter in the MuestraDatos(System.Data.DataRow row) method. The generated class code is compiled in memory, and from it an instance or object is created and is shown by the SelectedObject property of the control.

In order to generate the class code that will represent the DataRow, I have preferred to use template code (string) instead of CodeDom, since it makes me easier and controlled to work with.

string codigo = @"
using System;
using System.Data;
using System.ComponentModel;
using System.Reflection;

namespace miNamespace {
[TypeConverter(typeof(PropertySorter))]
public class miClase {
            
   private System.Data.DataRow m_Row = null;
";
   
foreach(System.Data.DataTable tabla in this.DS.Tables)
   
{
      
if(tabla != this.DS.Tables[0])
      
{
         codigo 
+= 
            
"public System.Collections.Hashtable Col"+ tabla.Columns[0].ColumnName + 
            
" = new System.Collections.Hashtable();\n";                
         codigo 
+= 
            
"public System.Collections.Hashtable _Col"+ tabla.Columns[0].ColumnName + 
            
" = new System.Collections.Hashtable();\n";
         }

      }

            
    codigo 
+= @"public miClase(System.Data.DataRow row)
    {
        m_Row = row;
}

I make iterations with the columns and tables associated of the DataRow in order to generate the fields, properties, attributes and enumerations. When the properties' values in the component are changed, immediately the respective fields in the DataRow are also changed.

foreach(System.Data.DataColumn col in this.Tabla.Columns)
{
   
if(this.ColCampos.ContainsKey(col.ColumnName))
   
{
      
if(ColRelaciones.ContainsKey(col.ColumnName))
      
{
         
string campo = 
             col.ColumnName 
+ "_Enum m_" 
             
+ ColNombreCampos[col.ColumnName].ToString();
         
string propiedad = col.ColumnName + "_Enum " + 
                  ColNombreCampos[col.ColumnName].ToString();
         codigo 
+=  "private " + campo  + ";\n";
         codigo 
+= "[Category(\"" + ColCategorias[col.ColumnName].ToString() 
            + "\"),Description(\"" + ColDescripciones[col.ColumnName].ToString()
            
+ "\"),PropertyOrder(" + ColOrden[col.ColumnName].ToString() 
            + "),ReadOnly(" + ColReadOnly[col.ColumnName].ToString().ToLower() 
            
+ ")]\n";
         codigo 
+=  "public " + propiedad + @"
         {
            get { return m_
" + ColNombreCampos[col.ColumnName].ToString() + @"; }
            set { 
               m_
" + ColNombreCampos[col.ColumnName].ToString() + @" = value;";
               codigo 
+= "m_Row[\"" + col.ColumnName + "\"] = _Col" + 
                                          col.ColumnName 
+ "[(int)value];";
               codigo 
+= @"
            }
         } 

         
";
      }

      
else
      
{
         
string campo = col.DataType.UnderlyingSystemType.ToString() + " m_" +
                             ColNombreCampos[col.ColumnName].ToString();
         
string propiedad = col.DataType.UnderlyingSystemType.ToString() + " " + 
                             ColNombreCampos[col.ColumnName].ToString();
         codigo 
+=  "private " + campo  + ";\n";
         codigo 
+= "[Category(\"" + ColCategorias[col.ColumnName].ToString() 
            + "\"),Description(\"" + ColDescripciones[col.ColumnName].ToString()
            
+ "\"),PropertyOrder(" + ColOrden[col.ColumnName].ToString()
            + "),ReadOnly(" + ColReadOnly[col.ColumnName].ToString().ToLower() +
            
")]\n";
         codigo 
+= @"
         public 
" + propiedad + @"
         {
            get { return m_
" + ColNombreCampos[col.ColumnName].ToString() + @"; }
            set { 
               m_
" +ColNombreCampos[col.ColumnName].ToString() + @" = value;";
               codigo 
+= "m_Row[\"" + col.ColumnName + "\"] = value;";
               codigo 
+= @"
            }
         }

         
";
      }

   }

}

foreach(System.Data.DataTable tabla in this.DS.Tables)
{
   
if(tabla != this.DS.Tables[0])
   
{
      codigo 
+=  @"

      public enum 
"; codigo += tabla.Columns[0].ColumnName + @"_Enum
      {
";
         
int i = 0;
         
foreach(System.Data.DataRow fila in tabla.Rows)
         
{
            codigo 
+= ObtieneEnumeracion(fila[1].ToString()) + " = " + 
               i 
+ ",\n";
            i 
++;
         }

         codigo 
+= "}";

      }

      }

  codigo 
+="}}";

  
return codigo;

If the DataRow has related tables, an enumeration is generated that allows to show the data in combobox way with understandable values for the end user, instead of key values used in database normalization. For example, the Customer_ID field of the DataRow would generate a Customer property of type enumeration with the names of the different clients so that the user chooses names instead of the ID codes, in the case that there is a Dataset with a table of clients with columns [Customer_Id] representing the ID and [Customer] the name of the client. This allows, in addition, to validate the input data.

If the DataRow has an associated DataSet, an enumeration by each one of the additional tables will be created that it has and whose columns are the code of a column of the DataRow and another column with the description for this code. The name of the property no longer will be the name of the column of the DataRow, but the name of the column description of the associate table.

 

使用DataPropertyGrid 

现在您可以把DataPropertyGrid加入到toolbox中,您可以在设计状态中修改它的属性。为了显示一条记录,您必须加入MuestraDatos方法,示例如下:
 

this.dataPropertyGrid1.MuestraDatos
        (
        Row, 
//DataRow
        "OrderID,Active,CustomerID,EmployeeID,OrderDate," + 
         
"ShippedDate,Freight,ShipCountry,ShipCity"//显示别名
        "Código,Activa,Cliente,Empleado,Fecha,Entrega," +
         
"Precio,Pais,Ciudad"//Nombre de campos
        "General,General,General,General,Tiempo,Tiempo," + 
         
"General,Localizacion,Localizacion"//Categorías
        "el Código de la orden,Define si la orden está activa o no," +
         
"Cliente de la orden,Empleado que registró la orden,
        Fecha de la orden,Fecha de entrega,Precio Total,País de" +
         " recepcion,Ciudad de recepción"//Descripciones
        "1,2,3,4,5,6,7,8,9"//Orden
        "1,0,0,0,0,0,0,0,0" //ReadOnly 1-true. 0-false
        );

这个控件使用很简单,具体的请参阅
http://www.codeproject.com/cs/miscctrl/DataPropertyGrid.asp#xx1096777xx

posted @ 2005-05-18 15:54  吴建明  阅读(2408)  评论(5编辑  收藏