扩展GridView控件(五)——固定表头、指定行或指定列

添加人:iyond七级(3513分)   添加时间:2007-03-29    阅读次数:3042  收藏此教程
介绍
平时使用GridView的时候会有固定表头、指定行或指定列的需求,就像Excel冻结行、列那样。其实我们可以用CSS来搞定。扩展一下GridView,通过设置几个属性来达到这样的功能。


控件开发
1、新建一个继承自GridView的类,另外为了保持滚动条状态,还要继承IPostBackDataHandler接口
    /// <summary>
    
/// 继承自GridView
    
/// </summary>

    [ToolboxData(@"<{0}:SmartGridView runat='server'></{0}:SmartGridView>")]
    
public class SmartGridView : GridView, IPostBackDataHandler
    
{

    }


2、新建一个FixRowCol类,有七个属性
using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;

namespace YYControls.SmartGridView
{
    
/// <summary>
    
/// 固定表头、指定行或指定列的实体类
    
/// </summary>

    [TypeConverter(typeof(ExpandableObjectConverter))]
    
public class FixRowCol
    
{
        
private bool _isFixHeader;
        
/// <summary>
        
/// 固定表头否?
        
/// </summary>

        [Description("固定表头否?"), Category("扩展"), DefaultValue(false), NotifyParentProperty(true)]
        
public virtual bool IsFixHeader
        
{
            
get return _isFixHeader; }
            
set { _isFixHeader = value; }
        }


        
private bool _isFixPager;
        
/// <summary>
        
/// 固定分页行否?
        
/// </summary>

        [Description("固定分页行否?"), Category("扩展"), DefaultValue(false), NotifyParentProperty(true)]
        
public virtual bool IsFixPager
        
{
            
get return _isFixPager; }
            
set { _isFixPager = value; }
        }


        
private string _fixRowIndices;
        
/// <summary>
        
/// 需要固定的行的索引(用逗号“,”分隔)
        
/// </summary>

        [Description("需要固定的行的索引(用逗号“,”分隔)"), Category("扩展"), NotifyParentProperty(true)]
        
public virtual string FixRowIndices
        
{
            
get return _fixRowIndices; }
            
set { _fixRowIndices = value; }
        }


        
private string _fixColumnIndices;
        
/// <summary>
        
/// 需要固定的列的索引(用逗号“,”分隔)
        
/// </summary>

        [Description("需要固定的列的索引(用逗号“,”分隔)"), Category("扩展"), NotifyParentProperty(true)]
        
public virtual string FixColumnIndices
        
{
            
get return _fixColumnIndices; }
            
set { _fixColumnIndices = value; }
        }


        
private System.Web.UI.WebControls.Unit _tableWidth;
        
/// <summary>
        
/// 表格的宽度
        
/// </summary>

        [Description("表格的宽度"), Category("扩展"), NotifyParentProperty(true)]
        
public System.Web.UI.WebControls.Unit TableWidth
        
{
            
get return _tableWidth; }
            
set { _tableWidth = value; }
        }


        
private System.Web.UI.WebControls.Unit _tableHeight;
        
/// <summary>
        
/// 表格的高度
        
/// </summary>

        [Description("表格的高度"), Category("扩展"), NotifyParentProperty(true)]
        
public System.Web.UI.WebControls.Unit TableHeight
        
{
            
get return _tableHeight; }
            
set { _tableHeight = value; }
        }


        
private bool _enableScrollState;
        
/// <summary>
        
/// 是否保持滚动条的状态
        
/// </summary>

        [Description("是否保持滚动条的状态"), Category("扩展"), DefaultValue(false), NotifyParentProperty(true)]
        
public bool EnableScrollState
        
{
            
get return _enableScrollState; }
            
set { _enableScrollState = value; }
        }


        
/// <summary>
        
/// ToString();
        
/// </summary>
        
/// <returns></returns>

        public override string ToString()
        
{
            
return "FixRowCol";
        }

    }

}


3、在继承自GridView的类中加一个复杂对象属性,该复杂对象就是第2步创建的那个FixRowCol
        private FixRowCol _fixRowCol;
        
/// <summary>
        
/// 固定表头、指定行或指定列
        
/// </summary>

        [
        Description(
"固定表头、指定行或指定列"),
        Category(
"扩展"),
        DefaultValue(
""),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        
public virtual FixRowCol FixRowCol
        
{
            
get
            
{
                
if (_fixRowCol == null)
                
{
                    _fixRowCol 
= new FixRowCol();
                }

                
return _fixRowCol;
            }

        }

4、重写OnRowDataBound以设置每个单元格的样式,从而实现固定表头、指定行或指定列的功能。
        /// <summary>
        
/// OnRowDataBound
        
/// </summary>
        
/// <param name="e"></param>

        protected override void OnRowDataBound(GridViewRowEventArgs e)
        
{
            
if (e.Row.RowType == DataControlRowType.Pager)
            
{
                
if (FixRowCol.IsFixPager)
                
{
                    
if (this.PagerSettings.Position == PagerPosition.Top || (this.PagerSettings.Position == PagerPosition.TopAndBottom && _isTopPager))
                    
{
                        
// TopPager固定行和列
                        e.Row.Cells[0].Attributes.Add("style""z-index:999; position: relative; top: expression(this.offsetParent.scrollTop); left: expression(this.offsetParent.scrollLeft);");
                        
// 现在是TopPager,之后就是BottomPager了,所以设置_isTopPager为false
                        _isTopPager = false;
                    }

                    
else if (this.PagerSettings.Position == PagerPosition.TopAndBottom && !_isTopPager)
                    
{
                        
// BottomPager只固定列
                        e.Row.Cells[0].Attributes.Add("style""z-index:999; position: relative; left: expression(this.offsetParent.scrollLeft);");
                        
// 现在是BottomPager,之后就是TopPager了,所以设置_isTopPager为true
                        _isTopPager = true;
                    }

                }

            }


            
if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Header)
            
{
                
// 给每一个指定固定的列的单元格加上css属性
                if (!String.IsNullOrEmpty(FixRowCol.FixColumnIndices))
                
{
                    
// 列索引
                    foreach (string s in FixRowCol.FixColumnIndices.Split(','))
                    
{
                        
int i;
                        
if (!Int32.TryParse(s, out i))
                            
throw new ArgumentException("FixColumnIndices""含有非整形的字符");
                        
if (i > e.Row.Cells.Count)
                            
throw new ArgumentOutOfRangeException("FixColumnIndices""溢出");

                        e.Row.Cells[i].Attributes.Add(
"style""position: relative; left: expression(this.offsetParent.scrollLeft);");
                    }

                }


                
bool isFixRow = false// 当前行是否固定
                if (FixRowCol.IsFixHeader && e.Row.RowType == DataControlRowType.Header)
                
{
                    isFixRow 
= true;
                }


                
if (!String.IsNullOrEmpty(FixRowCol.FixRowIndices) && e.Row.RowType == DataControlRowType.DataRow)
                
{
                    
// 行索引
                    foreach (string s in FixRowCol.FixRowIndices.Split(','))
                    
{
                        
int i;
                        
if (!Int32.TryParse(s, out i))
                            
throw new ArgumentException("FixRowIndices""含有非整形的字符");
                        
if (i > e.Row.Cells.Count)
                            
throw new ArgumentOutOfRangeException("FixRowIndices""溢出");

                        
if (i == e.Row.RowIndex)
                        
{
                            isFixRow 
= true;
                            
break;
                        }

                    }

                }


                
// 固定该行
                if (isFixRow)
                
{
                    
// 该行的每一个单元格
                    for (int j = 0; j < e.Row.Cells.Count; j++)
                    
{
                        
// 该单元格不属于固定列
                        if (String.IsNullOrEmpty(e.Row.Cells[j].Attributes["style"]) || e.Row.Cells[j].Attributes["style"].IndexOf("position: relative;"== -1)
                        
{
                            e.Row.Cells[j].Attributes.Add(
"style"" position: relative; top: expression(this.offsetParent.scrollTop);");
                        }

                        
// 该单元格属于固定列
                        else
                        
{
                            e.Row.Cells[j].Attributes.Add(
"style", e.Row.Cells[j].Attributes["style"+ "top: expression(this.offsetParent.scrollTop); z-index: 666;");
                        }

                    }

                }

            }


            
base.OnRowDataBound(e);
        }


5、增