DATAGRIDVIEW实现双表头及合计栏

来源:互联网 发布:淘宝如何申请退款退货 编辑:程序博客网 时间:2024/04/29 05:34

经常看到有同好问WINFORM里的DATAGRIDVIEW控件如何能实现双表头及合计栏,想来这是个棘手的问题,首先DATAGRIDVIEW的功能已很强大,重新写个控件费时费力,继承该控件增加一些功能自是首选。但往往做出来效果不大好,表头和合计栏看上去很“假”,不是位置就是外观让人感觉不大对劲。俺琢磨了下,用三个DATAGRIDVIEW“合并”成一个,并实现同步移动,基本可以满足要求,不注意根本看不出是三个拼起来的。

由于俺是业余编程爱好者,水平自是很菜,里面若有BUG,欢迎大家帮俺指正。

代码如下,VS2005编译通过。REBIND方法实现重新绑定、刷新数据的功能。

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace DataGridEx
{

    
public partial class DataGridEx : DataGridView 
    
{
        
private DataGridView FootGrid=null ;
        
private DataGridView DoubleGrid = null;
        
private bool _footvisible = false;
        
private bool _readonly=false ;
        
private bool _doublevisible = false;
        
private string[] FootText;
        
private int[] doubleGridOffset;
        
private int initHeight;

        
public bool FootVisible
        
{
            
get
            
{
                
return _footvisible;
            }

        }


        
public bool DoubleVisible
        
{
            
get
            
{
                
return _doublevisible;
            }

        }


        
public bool IsReadOnly
        
{
            
get
            
{
                
return _readonly;
            }

            
set
            
{
                _readonly 
= value;
                
if (_readonly)
                
{
                    
foreach (DataGridViewColumn dv in this.Columns)
                    
{
                        dv.SortMode 
= DataGridViewColumnSortMode.NotSortable;
                    }

                }

            }

        }


        
public DataGridEx()
        
{
            InitializeComponent();
        }


        
设置DataGrid的列标题显示文字 

        
设置合计行

        
设置双表头

        
public void ReBind()
        
{
            
if (_footvisible)
            
{
                
try
                
{
                    FootGrid.HorizontalScrollingOffset 
= 0;

                    
decimal[] Compute = new decimal[FootText.Length];
                    
for (int j = 0; j < this.ColumnCount; j++)
                    
{
                        
if (FootText[j] != string.Empty)
                        
{
                            
if (FootText[j] == "S")
                            
{
                                
for (int k = 0; k < this.RowCount; k++)
                                
{
                                    Compute[j] 
+= Convert.ToDecimal(this[j, k].Value == DBNull.Value ? 0 : this[j, k].Value);
                                }

                                FootGrid.Columns[j].HeaderText 
= Compute[j].ToString(this.Columns[j].DefaultCellStyle.Format);
                            }

                            
else
                            
{
                                FootGrid.Columns[j].HeaderText 
= FootText[j] + this.RowCount;
                            }

                        }

                    }

                }

                
catch (DataException e)
                
{
                    MessageBox.Show(e.Message 
+ "请重新设置数据格式!");
                }

            }

        }


        
private void FootGrid_Scroll(object sender, ScrollEventArgs e)
        
{
            
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
            
{
                
this.DoubleBuffered = true;
                
this.HorizontalScrollingOffset = e.NewValue;
                
if (DoubleGrid != null)
                
{
                    DoubleGrid.HorizontalScrollingOffset 
= e.NewValue;
                }

                
this.DoubleBuffered = false;
            }

        }


        
private void DataGridEx_Scroll(object sender, ScrollEventArgs e)
        
{
            
if (DoubleGrid != null && FootGrid == null && e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
            
{
                DoubleGrid.HorizontalScrollingOffset 
= e.NewValue;
            }

        }


        
private void DataGridEx_DataSourceChanged(object sender, EventArgs e)
        
{
            ReBind();
        }


        
private void DataGridEx_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        
{
            
if (_footvisible )
            
{
                
this.HorizontalScrollingOffset = FootGrid.HorizontalScrollingOffset;
            }

        }




        
private void DataGridEx_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        
{
            
if (_footvisible)
            
{
                
this.HorizontalScrollingOffset = FootGrid.HorizontalScrollingOffset;
                
int colHeadHeight = (this.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) > this.Width ?
                    FootGrid.ColumnHeadersHeight 
* 2 : FootGrid.ColumnHeadersHeight);

                
this.Height = initHeight - colHeadHeight - (_doublevisible ? FootGrid.ColumnHeadersHeight : 0);
                FootGrid.Location 
= this.Location + new Size(0this.Height);
                FootGrid.Size 
= new Size(this.Width, colHeadHeight);

                
int index = e.Column.Index;
                FootGrid.Columns[index].Width 
= e.Column.Width;
                
            }

            
if (_doublevisible)
            
{
                
int offset=0;
                
for (int i = 0; i < doubleGridOffset.Length; i++)
                
{
                    
if (e.Column.Index <= doubleGridOffset[i])
                    
{
                        offset 
= i;
                        
break;
                    }

                }

                DoubleGrid.Columns[offset].Width  
= 5;
                
for (int j = (offset == 0 ? 1 : doubleGridOffset[offset - 1+ 1); j <= doubleGridOffset[offset]; j++)
                
{
                    
if (this.Columns[j].Visible)
                    
{
                        DoubleGrid.Columns[offset].Width  
+= this.Columns[j].Width;
                    }

                 }

                DoubleGrid.Columns[offset].Width 
-= 5;
                DoubleGrid.HorizontalScrollingOffset 
= FootGrid.HorizontalScrollingOffset;
            }

        }


        
private void DataGridEx_VisibleChanged(object sender, EventArgs e)
        
{
            
if (FootGrid!=null )
            
{
                FootGrid.Visible 
=this .Visible;
            }

        }


        
private void DataGridEx_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        
{
            
if (e.Button == MouseButtons.Right && e.RowIndex > -1)
            
{
                
this.Rows[e.RowIndex].Selected = true;
            }

        }


        
private void DataGridEx_KeyPress(object sender, KeyPressEventArgs e)
        
{
            
if (e.KeyChar==(char)Keys.Space && this.CurrentRow !=null )
            
{
                
this.OnCellDoubleClick(new DataGridViewCellEventArgs(0 , this.CurrentRow.Index));
            }

        }

            

    }



}

 

说明:DATAGRIDVIEW里提供了SCROLL事件,可以做出滚动条同步的效果。另外新增的COLUMNWIDTHCHANGED事件,可以在主表列宽改变时同步改变合计栏、双表头的列宽。

 

 

原创粉丝点击