DataGridView樣式--進階


要定製自已的DataGridView列樣式,事實上我們是要定製的是單元格的樣式,所謂列樣式,只是將同一列的所有單元格設定成相同格式而已,那麼如何做呢,有兩種方式:
(1)一種簡單的方式就是重寫DataGridViewCell的paint事件及其它觸發事件,從而得到想要的各種單元格效果,然後再簡單的重寫一個相應的DataGridViewColumn類,就可以了,但是這個方法需要自已去畫控件,對一般人來說還是一件麻煩的事.
(2)還有另一種方式,那就是在DataGridViewCell中放一個我們需要的控件,我們只需要改變這個控件,就可以達到改變單元格樣式的目的,這種方法就方便多了(當然,對這個控件是有要求的,它必須實現IDataGridViewEditingControl接口).
然後我們再重寫一個DataGridViewCell,在這裡可以控製當單元格進入編輯狀態時如何初始化這個用於編輯的控件.(在顯示狀態時如何控製控件的顯示,我還不知道.)
最後我們再重寫一個相應的DataGridViewColumn類就全搞定了.

下面以製作DataGridViewDateTimeColumn為例,介紹第(2)種方式的具體做法,相應的解析都在代碼裡面.

1.編寫DataGridViewDateTimeEditingControl類
這個類繼承自DateTimePicker,同時它必須實現IDataGridViewEditingControl接口,這個接口的定義如下:

   //  為裝載於 System.Windows.Forms.DataGridView 之儲存格的控制項定義通用功能。
     public   interface  IDataGridViewEditingControl
    {
        
//  取得或設定包含儲存格的 System.Windows.Forms.DataGridView。
        DataGridView EditingControlDataGridView {  get set ; }

        
//  取得或設定編輯器所修改之儲存格的格式化值。
         object  EditingControlFormattedValue {  get set ; }

        
//  取得或設定裝載儲存格之父資料列的索引。
         int  EditingControlRowIndex {  get set ; }

        
//  取得或設定值,指出編輯控制項的值是否與裝載儲存格的值不同。
         bool  EditingControlValueChanged {  get set ; }

        
//  取得當滑鼠指標放在 System.Windows.Forms.DataGridView.EditingPanel 上方,但不在編輯控制項上方時所用的游標。
        Cursor EditingPanelCursor {  get ; }

        
//  取得或設定值,指出每當值變更時儲存格內容是否需要重新調整位置。
         bool  RepositionEditingControlOnValueChange {  get ; }

        
//  變更控制項的使用者介面 (UI),使其與指定的儲存格樣式一致。
         void  ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle);

        
//  判斷指定的按鍵是否為編輯控制項應該處理的標準輸入按鍵,或是 System.Windows.Forms.DataGridView 應該處理的特殊按鍵。
         bool  EditingControlWantsInputKey(Keys keyData,  bool  dataGridViewWantsInputKey);

        
//  擷取儲存格的格式化值。
         object  GetEditingControlFormattedValue(DataGridViewDataErrorContexts context);

        
//  準備目前所選的儲存格來編輯。
         void  PrepareEditingControlForEdit( bool  selectAll);
    }

  下面是DataGridViewDateTimeEditingControl 的源代碼:

  public   class  DataGridViewDateTimeEditingControl : DateTimePicker, IDataGridViewEditingControl
    {
        
protected   int  rowIndex;
        
protected  DataGridView dataGridView;
        
protected   bool  valueChanged  =   false ;

        
public  DataGridViewDateTimeEditingControl()
        {
        }

        
// 重寫基類事件OnValueChanged
         protected   override   void  OnValueChanged(EventArgs e)
        {
            
// 估計這裡調用了GetEditingControlFormattedValue函數,
            
// 從而將控件的新值傳遞給單元格,做為單元格的新值
             base .OnValueChanged(e);
            
// 通知DataGridView,控件所在單元格的值發生變化.
            NotifyDataGridViewOfValueChange();
        }

        
// 通知DataGridView,控件所在單元格的值發生變化
         private   void  NotifyDataGridViewOfValueChange()
        {
            
this .valueChanged  =   true ;
            dataGridView.NotifyCurrentCellDirty(
true );
        }

        
#region  IDataGridViewEditingControl接口的實現

        
///   <summary>
        
///  獲取或設置儲存格所在的DataGridView
        
///   </summary>
         public  DataGridView EditingControlDataGridView
        {
            
get
            {
                
return   this .dataGridView;
            }
            
set
            {
                
this .dataGridView  =  value;
            }
        }


        
///   <summary>
        
///  獲取或設置儲存格格式化後的值
        
///   </summary>
         public   object  EditingControlFormattedValue
        {
            
get
            {
                
return   this .Text;
            }
            
set
            {
                Text 
=  value.ToString();
                
//   當控件的Text值發生變化時,通知DataGridView,控件所在的單元格的值也發生變化.
                NotifyDataGridViewOfValueChange();
            }
        }

        
///   <summary>
        
///  在Cell被編輯的時候光標顯示
        
///   </summary>
         public  Cursor EditingPanelCursor
        {
            
get
            {
                
return  Cursors.IBeam;
            }
        }
        
///   <summary>
        
///  取得或設定值,指出每當值變更時儲存格內容是否需要重新調整位置。
        
///   </summary>
         public   virtual   bool  RepositionEditingControlOnValueChange
        {
            
get
            {
                
return   false ;
            }
        }
        
///   <summary>
        
///  取得或設定儲存格所在行
        
///   </summary>
         public   int  EditingControlRowIndex
        {
            
get
            {
                
return   this .rowIndex;
            }
            
set
            {
                
this .rowIndex  =  value;
            }
        }
        
///   <summary>
        
///  取得或設定值,指出編輯控制項的值是否與裝載儲存格的值不同。
        
///   </summary>
         public   bool  EditingControlValueChanged
        {
            
get
            {
                
return  valueChanged;
            }
            
set
            {
                
this .valueChanged  =  value;
            }
        }
        
///   <summary>
        
///  擷取儲存格的格式化後的值。
        
///   </summary>
        
///   <param name="context"> 錯誤上下文 </param>
        
///   <returns></returns>
         public   virtual   object  GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            
return  Text;
        }
        
///   <summary>
        
///  判斷指定的按鍵是否為編輯控制項應該處理的標準輸入按鍵,或是 System.Windows.Forms.DataGridView 應該處理的特殊按鍵。
        
///   </summary>
        
///   <param name="keyData"></param>
        
///   <param name="dataGridViewWantsInputKey"></param>
        
///   <returns></returns>
         public   bool  EditingControlWantsInputKey(Keys key,  bool  dataGridViewWantsInputKey)
        {
            
//  Let the DateTimePicker handle the keys listed.
             switch  (key  &  Keys.KeyCode)
            {
                
case  Keys.Left:
                
case  Keys.Up:
                
case  Keys.Down:
                
case  Keys.Right:
                
case  Keys.Home:
                
case  Keys.End:
                
case  Keys.PageDown:
                
case  Keys.PageUp:
                    
return   true ;
                
default :
                    
return   false ;
            }
        }
        
///   <summary>
        
///  準備目前所選的儲存格來編輯。
        
///   </summary>
        
///   <param name="selectAll"></param>
         public   void  PrepareEditingControlForEdit( bool  selectAll)
        {
        }

        
///   <summary>
        
///  變更控制項的介面 (UI),使其與當前單元格的樣式一致。
        
///   </summary>
        
///   <param name="dataGridViewCellStyle"></param>
         public   void  ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            
this .Font  =  dataGridViewCellStyle.Font;
            
this .CalendarForeColor  =  dataGridViewCellStyle.ForeColor;
            
this .CalendarMonthBackground  =  dataGridViewCellStyle.BackColor;
        }

        
#endregion
    }

2.編寫DataGridViewDateTimeCell類   

  public   class  DataGridViewDateTimeCell:DataGridViewTextBoxCell
    {
        
private   bool  showUpDown;
        
public  DataGridViewDateTimeCell()
        {
        }

        
///   <summary>
        
///  在這裡初始化單元格編輯時的所用到的控件
        
///   </summary>
        
///   <param name="rowIndex"></param>
        
///   <param name="initialFormattedValue"></param>
        
///   <param name="dataGridViewCellStyle"></param>
         public   override   void  InitializeEditingControl( int  rowIndex,  object  initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            
base .InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            DataGridViewDateTimeEditingControl ctl 
=  DataGridView.EditingControl  as  DataGridViewDateTimeEditingControl;

     
#region  設定DataGridViewDateTimeEditingControl控件的屬性
     
// 設定Value
            ctl.Value  =  (DateTime) this .Value;         
            DataGridViewColumn dgvColumn 
=   this .OwningColumn;
            
if  (dgvColumn  is  DataGridViewDateTimeColumn)
            {
                DataGridViewDateTimeColumn dateTimeColumn 
=  dgvColumn  as  DataGridViewDateTimeColumn;
                
//
                
// 設定ShowUpDown
                
//
                ctl.ShowUpDown  =   this .ShowUpDown;
                
//
                
// 設定Format
                
//
                 switch  (dateTimeColumn.DefaultCellStyle.Format)
                {
                    
case   " d " :
                        ctl.Format 
=  DateTimePickerFormat.Short;
                        
break ;
                    
case   " D " :
                        ctl.Format 
=  DateTimePickerFormat.Long;
                        
break ;
                    
case   " f " :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=   " yyyy年M月d日 tt hh:mm " ;
                        
break ;
                    
case   " F " :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=   " yyyy年M月d日 HH:mm:ss " ;
                        
break ;
                    
case   " g " :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=   " yyyy/MM/dd tt hh:mm " ;
                        
break ;
                    
case   " G " :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=   " yyyy/MM/dd HH:mm:ss " ;
                        
break ;
                    
case   " t " :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=   " tt hh:mm " ;
                        
break ;  
                    
case   " T " :
                        ctl.Format 
=  DateTimePickerFormat.Time;
                        ctl.CustomFormat 
=   " HH:mm:ss " ;
                        
break ;
                    
case   " M " :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=   " M月d日 " ;
                        
break ;
                    
default :
                        ctl.Format 
=  DateTimePickerFormat.Custom;
                        ctl.CustomFormat 
=  dateTimeColumn.DefaultCellStyle.Format;
                        
break ;
                }

            }
     
#endregion
        }
        
// 一個自定義屬性,用於改變控件的編輯方式
        
// 為什麼要這個屬性,DataGridViewDateTimeEditingControl繼承自DateTimePicker,DateTimePicker自已就有這個屬性,
        
// 直接改不就可以控製控件的外觀了嗎?這裡主要是為了將該屬性暴露出來,從而可以在本控件以外進行修改.
         public   virtual   bool  ShowUpDown
        {
            
get
            {
                
return   this .showUpDown;
            }
            
set
            {
                
this .showUpDown  =  value;
            }
        }
        
// 編輯狀態時控件的類型
         public   override  Type EditType
        {
            
get
            {
                
return   typeof (DataGridViewDateTimeEditingControl);
            }
        }
        
// 單元格值的類型
         public   override  Type ValueType
        {
            
get
            {
                
return   typeof (DateTime);
            }
        }
        
// 單元格默認值
         public   override   object  DefaultNewRowValue
        {
            
get
            {
                
return  DateTime.Now;
            }
        }
    }

3.編寫DataGridViewDateTimeColumn 類  

public   class  DataGridViewDateTimeColumn : DataGridViewColumn
    {
        
private    bool  showUpDown ;
        
public  DataGridViewDateTimeColumn() :  base ( new  DataGridViewDateTimeCell())
        {

        }
        
public   override  DataGridViewCell CellTemplate
        {
            
get
            {
                
return   base .CellTemplate;
            }
            
set
            {
                
if  (value  !=   null   &&   ! value.GetType().IsAssignableFrom( typeof (DataGridViewDateTimeCell)))
                {
                    
throw   new  InvalidCastException( " 不是DataGridViewDateTimeCell " );
                }
                
base .CellTemplate  =  value;
            }
        }

        
// 要實現自定義屬性設計時的保存必須同時重寫Clone方法
        
// 在這裡我們自定義了一個屬性ShowUpDown,所以要重寫該方法
         public   override   object  Clone()
        {
            DataGridViewDateTimeColumn col 
=  (DataGridViewDateTimeColumn) base .Clone();
            col.ShowUpDown 
=   this .showUpDown;
            
return  col;
        }

        
// 自定義的屬性
        
// 在Cell中存在的屬性,在Column中我們一般也應該有相應的屬性.
         public    bool  ShowUpDown
        {
            
get
            {
                
return  showUpDown;
            }
            
set
            {
                
if  ( this .showUpDown  !=  value)
                {
                    
this .showUpDown  =  value;
                    DataGridViewDateTimeCell dateTimeCell 
=  (DataGridViewDateTimeCell) this .CellTemplate;
                    dateTimeCell.ShowUpDown 
=  value;
                    
if  ( this .DataGridView  !=   null   &&   this .DataGridView.Rows  !=   null )
                    {
                        
int  rowCount  =   this .DataGridView.Rows.Count;
                        
for  ( int  x  =   0 ; x  <  rowCount; x ++ )
                        {
                            DataGridViewCell dataGridViewCell 
=   this .DataGridView.Rows.SharedRow(x).Cells[x];
                            
if  (dataGridViewCell  is  DataGridViewDateTimeCell)
                            {
                                dateTimeCell 
=  (DataGridViewDateTimeCell)dataGridViewCell;
                                dateTimeCell.ShowUpDown 
= value;
                            }
                        }
                    }
                }

            }
        }
    } 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值