Makale Özeti

Datagrid e combo box eklemek, datagrid e takvim eklemek, Cell'leri mask'lamak, Validation koymak, değişen satırları ve yeni kayıtları kod yazmadan generic olarak query oluşturup kaydetmek hep sorun olmuştur. Bu problemden yola çıkarak, generik bir DataGrid yazmayı düşündüm. DataGridView controlunu base alarak. Yeni bir user control oluşturdum.

Makale

Generic DataGridView,
By Yildirim Kocdag

Datagrid e combo box eklemek, datagrid e takvim eklemek, Cell'leri mask'lamak, Validation koymak, değişen satırları ve yeni kayıtları kod yazmadan generic olarak query oluşturup kaydetmek hep sorun olmuştur.

Bu problemden yola çıkarak, generik bir DataGrid yazmayı düşündüm. DataGridView controlunu base alarak. Yeni bir user control oluşturdum. Bu yeni objeye,

1) addCombo,
2) addMask,
3) addValidation,
4) addCalendar,
5) fillAll.

methodları ve

1)DataColumns,
2)DataColumnsTable,
3)DataConnection

propertyleri ekledim.
 


Resim 1 - Properties

Sonuçta bu yeni metodlar ve propertyler ile sadece bir kaç satır kod ile çok kullanışlı bir datagrid elde
edebiliyoruz. Combo,calendar,mask,validation eklemek için uzun uzun kod yazmıyoruz. Veya kayıt için herhangi bir update veya insert cümleciği yazmamıza gerek kalmıyor(Sistem kendi üretiyor).


Kod Hakkında
 

 private void Form1_Load(object sender, EventArgs e)
    {
        genericDataGridView1.FillAll();
        genericDataGridView1.AddCombo("EmployeeID", "EmployeeID", "Employees", "FirstName",         "EmployeeID", " order by FirstName");
        genericDataGridView1.AddValidation("Freight", true,ValidationStyle.NumericInt, "must be an integer");
        genericDataGridView1.AddCalendar("OrderDate", "OrderDate");
        genericDataGridView1.AddMask("ShipPostalCode", "ShipPostalCode", "(99)0-0");
}

Yukarıda görüldüğü gibi form'un loadında gerekli tanımlamaları yapmak ve ayrıca  control üzerindeki propertyleri set etmek yeterli.
 

Birazda Generic DatagridView Component'imizin kodundan bahsedelim,

Generic DataGridView'ın kod yapısını 11 ana başık altında toplayabiliriz, bunlar; New Properties, Fill All, AddCombo, AddCalendar, AddMask, AddValidation, RowSave, Events, ValidationControls,  DataGridViewCalendarColumn ve DataGridViewMaskColumn.

Bu kod parçacıklarından önemli olanlarından kısaca örnek vererek bahsetmeye çalışacağım.

AddCombo :
Burada dikkat edilebilecek en önemli nokta DataGridView'ın DataSource'u set edildikten sonra combonun ekleneceği column'ın önce remove edilmesi daha sonra aynı isim ile fakat DataGridViewComboBoxColumn olarak DataGridView'a eklenmesi. DatagridView'a eklendikten sonra column sırası olarak en sonra görünmektedir. Bundan dolayı DataColumns property'sini kullanarak Grid üzerindeki yeri tekrar hesaplanır ve display index'i set edilir.

public void AddCombo(string ColumnName, string HeaderText, string SourceTable, string DisplayColumn, string ValueMember, string SWhere)
{
   Columns.Remove(ColumnName);
   System.Data.SqlClient.SqlConnection cn;
   cn = new SqlConnection(DataConnection);
   cn.Open();
   string sql;
   sql = "Select " + DisplayColumn + " as LB," + ValueMember + " as VL from " + SourceTable + " " + SWhere;
   System.Data.SqlClient.SqlDataAdapter da_addcombo = new SqlDataAdapter(sql, cn);
   System.Data.DataTable dt_addcombo;
   dt_addcombo = new System.Data.DataTable();
   da_addcombo.Fill(dt_addcombo);
   DataGridViewComboBoxColumn column_addcombo = new DataGridViewComboBoxColumn();
   column_addcombo.DataSource = dt_addcombo;
   column_addcombo.DisplayMember = "LB";
   column_addcombo.ValueMember = "VL";
   column_addcombo.DataPropertyName = ColumnName;
   column_addcombo.Name = ColumnName;
   column_addcombo.HeaderText = HeaderText;
   Columns.Add(column_addcombo);
   int j, i;
   string[] k;
   char a;
   a = ',';
   k = m_DataColumns.Split(a);
   i = k.Length - 1;
   j = 0;
   while ((j < i) && (k[j].IndexOf(ColumnName) == -1))
      {
         j = j + 1;
      }
   Columns[i].DisplayIndex = j;
}
 

AddValidation : Bu methoddaki en önemli özellik her tanımlanan validation için datavalidation'da (kendi datatable'ı) bir satır ekliyor olmasıdır. Aldığı parametreler, ColumnName, BlankControl, ValidationType ve ValidationMessage'dır. Burada dikkat etmemiz gereken nokta ise ValidationType'dır. Projeyi yazarken kendi tanımladığım validation type'lar, NumericInt, NumericDouble, DateTime ve Email kontrolleriydi. Bu kontrol'ler arttırılarbilir veya değiştirilebilir. Validation olayı onCellValidating Eventinde kontrol edilir. İlk olarak dtValidation Datatable'ının ilk column'ı blank data'nın kontrolünün olup olmadığına bakılır. Daha sonra 2.column'daki validationtype'a bakarak. Validation'un nasıl yapılacağına karar verilir.
 

protected override void OnCellValidating(System.Windows.Forms.DataGridViewCellValidatingEventArgs e)
{
   int i, j;
   j = dtValidation.Rows.Count - 1;
   if (j != -1)
      {
         i = 0;
         bool check = false;
         System.Data.DataView dv = new System.Data.DataView(dtValidation, "Name='" + this.Columns               [e.ColumnIndex].Name + "'", null, System.Data.DataViewRowState.CurrentRows);
         if (dv.Count == 1)
            {
            if ((bool)dv[0][1])
               {
               if (String.IsNullOrEmpty(e.FormattedValue.ToString()))
                  {
                     this.Rows[e.RowIndex].ErrorText = "Empty Text";
                     e.Cancel = true;
                  }
            }
            if ((dv[0][2].ToString()) != "")
               {
                     switch (dv[0][2].ToString())
                        {
                           case "0":
                              check = IsNumericInt(e.FormattedValue.ToString());
                              break;
                           case "1":
                              check = IsNumericDouble(e.FormattedValue.ToString());
                              break;
                           case "2":
                              check = IsEmail(e.FormattedValue.ToString());
                              break;
                           case "3":
                               check = IsDate(e.FormattedValue.ToString());
                              break;
                       }
                  if (check)
                        {
                              this.Rows[e.RowIndex].ErrorText = dv[0][3].ToString();
                              e.Cancel = check;
                        }
                  }

 
            }
       }
      base.OnCellValidating(e);
}
 


AddMask :
Bu methoddaki en önemli özellik ise MaskedTextColumn Type'ını kullanıyor olmasıdır. Bu type tıpkı DataGridViewCalendarColumn gibi, datagridview'ın özelliklerinden biri değildir. Dolayısıyla kendimiz yazmamız gerekiyor, bu Column Type'ından bahsetmemeye çalışacağım ama herhangi bir soru gelirse cevaplamaktan mutluluk duyarım. DataGridView üzerine eklenmesi oldukça basittir, Combo ekler gibi özelliklerini tanımladıktan sonra aşağıda görüldüğü gibi mask'ı tanımlanır.

public void AddMask(string ColumnName, string HeaderText, string MaskStr)
{
      Columns.Remove(ColumnName);
      MaskedTextColumn column_addmask;
      column_addmask = new MaskedTextColumn();
      column_addmask.DataPropertyName = ColumnName;
      column_addmask.Name = ColumnName;
      column_addmask.HeaderText = HeaderText;
      column_addmask.maskA(MaskStr);
      Columns.Add(column_addmask);
      int j, i;
      string[] k;
      char a;
      a = ',';
      k = m_DataColumns.Split(a);
      i = k.Length - 1;
      j = 0;
      while ((j < i) && (k[j].IndexOf(ColumnName) == -1))
            {
                  j = j + 1;
            }
      Columns[i].DisplayIndex = j;
}

Dikkat edilmesi gerekilen noktalar,
Projeyi oluştururken Northwind Database'ini ve Orders tablosunu kullandım. Sistemin kendi kendine update ve insert querylerini oluştururabilmesi için string ve datetime şeklinde DML'inde tırnak kullanacak column'lar için column adından sonra aşağıda görüldüğü gibi % konulması gerekmektedir.
 

MyGDGV.DataColumns = "OrderID,CustomerID%,OrderDate%,EmployeeID,Freight,ShipPostalCode%"

Bir başka nokta ise DataColumns tanımlanırken ilk Column'ın Identity Column olmasıdır. Orders tablosundaki OrderID column'ı gibi.

Birazcıkta Ekran Görüntülerini Koyalım,

                                                                                       Resim 2 - Form Load


                                                                                      Resim 3 - Calendar Column


                                                                                      Resim 3 - Combo Column


                                                                                      Resim 4 - Validation


                                                                                      Resim 5 - Mask


                                                                                      Resim 6 - Saved Row

 

Not : Client'ın veya SQL'in tarih formatı veya nokta-virgül ayıraçlarından dolayı buglar oluşabilir. Soru sormak için çekinmeyin lütfen. Kaynak kodunda c# ile hazırlanmış GenericDataGridView ve Test için kullanabileceğiniz iki farklı proje(c# ve VB.net) i bulacaksınız. Makalenin tarafımdan yazılmış orjinal halini GenericDataGridView olarak internette(codeproject.com veya dotnetheaven.com adreslerinde) bulabilirsiniz. Projenin kodunu buradan indirebilirsiniz.


 

Kodlar