DataGridHelper工具






4.71/5 (25投票s)
一个辅助类,用于方便地为 ASP.NET DataGrid 组件添加 CSS 类和确认对话框。
- 下载演示 Web 项目 - 35.7 Kb
- 下载源代码 - 2.74 Kb (仅包含 DataGridHelper类)
- 下载安装程序 - 3.88 Kb (将 DataGridHelper类安装为 Web 应用程序中的 HttpModule)

引言
当使用 Visual Studio .NET 创建 ASP.NET 页面时,属性生成器是一个非常好的工具,可以快速地为单个页面上的 ASP.NET DataGrid 控件自定义功能或颜色。但是,我一直非常怀念能够以编程方式为不同元素类型(Header、Footer、Item、AlternatingItem 等)添加 CSS 类名,这样我就可以从一个 CSS 文件中改变我解决方案中所有 DataGrid 的外观。我在网上找过解决方案,但没找到,所以我自己创建了一个。这个小辅助类还有一些其他技巧。
DataGridHelper 可以
- 为 DataGrid中的所有行、单元格和按钮添加 CSS 类名。例如 "Item_row"、"Header_cell"、"Button_Update" 等。(一行代码)。
- 为 DataGrid中的所有行和/或单元格添加属性。(一行代码)。
- 为 DataGrid列中的按钮添加 JavaScript 确认对话框。(一行代码)。
v. 1.2 - IHttpModule 实现 
对于那些想要在不写一行代码的情况下为 DataGrid 添加 CSS 类的人来说,DataGridHelper 类现在实现了 IHttpModule 接口。这使得在整个解决方案(通过编辑 web.config 文件)或服务器上的所有解决方案(通过编辑 machine.config 文件)中自动添加 CSS 类成为可能。
在此查看如何做到 [这里]。
使用代码
我创建了一个小 Web 项目来向您展示如何使用这个辅助类。大多数方法都很直接,但是向 DataGrid 添加 CSS 有点棘手:您必须在绑定 DataGrid 数据之前调用此方法。
原因是我找不到除了附加到 DataGrid 的 ItemDataBound 事件之外的任何其他方法来访问 DataGrid 的 Header、Footer、Pager 等行。
我尝试遍历 DataGrid.Items,但这只能访问 Item、AlternatingItem、SelectedItem 和 EditItem 项。
这是核心方法
//Adds CSS class names to cells, rows and buttons in a datagrid
public static void AddCssToDataGrid(DataGrid aGrid); //(updated in version 1.1)
//Adds an attribute to all cells in a DataGrid
public static void AddAttributesToCells(DataGrid theGrid, 
       string attributeKey, string attributeValue);
//Adds an attribute to all rows in a DataGrid
public static void AddAttributesToRows(DataGrid theGrid, 
       string attributeKey, string attributeValue);
//Adds a confirm javascript dialog to the buttons in a column of a DataGrid
public static void AddConfirm(DataGrid theGrid, 
                   int columnNumber, string question);
我包含的示例项目遵循了许多 Web 项目的传统模式
- Page_Load- 检查 Session 中是否有数据。- 如果没有,则将其从磁盘加载到 Session 中。
 
- 事件 
- 如果点击了 "Delete" - 则删除该行。
- 如果点击了 "Load data" - 则重新加载数据。
 
- PreRender- 绑定数据并在最后进行修改。
 
对于不熟悉此方法的人来说,了解 ASP.NET 页面的处理顺序会很有帮助。
- Page_Load最先执行,因此这是一个确保数据加载的好地方。
- 所有事件随后处理,这包括所有回发事件(按钮点击等),此时是删除、编辑和添加内容的时候。
- PreRender最后运行,此时是呈现数据当前状态的时候。换句话说,就是 "databind"。
换句话说:“加载数据” - “编辑数据” - “显示数据”。
整个 Web 项目本身并不是一个很大的应用程序。它完全是为了展示 DataGridHelper 类功能的。
注意事项
- 我有一个外部 CSS 文件 "sample.css",其中包含 "Item_cell"、"AlternatingItem_cell" 等样式。在将 CSS 类添加到单元格和行后,这会自动为 DataGrid着色。
- 我有一个外部 JavaScript 文件 "scripts.js",其中包含一个小的 DHTML 脚本,可以动态更改 HTML 对象的 CSS 类,使其在视觉上呈现不同的外观,具体取决于其类。
- 为了避免在示例项目中包含数据库,我创建了一个类型化数据集,将数据库表加载到其中,并使用 DataSet的WriteXml()方法将其写入磁盘。这样我就可以(并且确实)使用ReadXml()方法将数据重新加载到DataSet中。
- 我在页面上有一个名为 dgPersons的DataGrid。使用 Visual Studio 中的属性生成器,我在此DataGrid中添加了一个隐藏的第一列(第 0 列),其中包含DataTable中行的主键。这样,当用户单击行中的 Delete 按钮时,我就可以轻松地在DataTable中查找相应的行。

示例项目的代码
DataSet 作为成员变量
我将我的类型化数据集声明为成员变量,以便所有方法都可以访问它。
//the dataset containing the table with our persons
protected dsPersons persons;
Page_Load 加载数据
页面加载时发生的所有事情就是加载数据。
private void Page_Load(object sender, System.EventArgs e)
{
    //load the data to display
    LoadData();
}
LoadData() 方法
这是从 Page_Load 调用 的 LoadData 方法。
public void LoadData()
{
    //if we don't have any data in Session state
    if(Session["persons"] == null)
    {
        //find the full path to the xml file
        string path = Server.MapPath("persons.xml");
        //create a new, empty dataset
        persons = new dsPersons();
        //fill it with data from the file
        persons.ReadXml(path);
        //save it in Session state
        Session["persons"] = persons;
    }
    //in all cases, we can now retrieve 
    //the dataset from Session state
    persons = (dsPersons) Session["persons"];
}
...此时我们确信 Session 中有一个已加载的数据集,因此如果此页面视图是由点击 Delete 按钮引起的,那么我们就可以继续在该 DataTable 中将该行标记为已删除。
Delete 事件 查找并删除一个人。
private void dgPersons_DeleteCommand(object source, 
              System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
    //we find the id of this row 
    //by looking in the hidden first colum
    int id = int.Parse(e.Item.Cells[0].Text);
    //this person we look up in the Table,
    //and mark the row for deletion
    persons.person.FindByid(id).Delete();
}
如果用户没有点击 "Delete" 而是点击了 "Reload data",那么此事件也会在页面生命周期的此时发生,我们可以重新加载数据。
从文件重新加载数据
private void btnReloadData_Click(object sender, System.EventArgs e)
{
    //empties the Session state of data
    Session["persons"] = null;
    //reloads the dataset from disk
    LoadData();
}
无论如何,PreRender 事件最后发生,这是我的辅助类开始工作的地方。
PreRender 显示数据。
// This method runs right before the page
// and all its controls are converted to HTML
// and sent to the client's browser.
// This is the place to databind,
// and therefore we do all the adding of 
// attributes, etc. here.
private void WebForm1_PreRender(object sender, System.EventArgs e)
{
    //if the checkbox is checked
    //then we add CSS class names
    //so the CSS file's contents get to work
    if (chkAddCSS.Checked)
        DataGridHelper.AddCssToDataGrid(dgPersons);
    
    //set the datagrid's datasource to the
    //table containing our people
    dgPersons.DataSource = persons.person;
    //bind the data
    dgPersons.DataBind();
    //if the user wants to add deleteconfirmation
    if(chkAddDeleteConfirmation.Checked)
    {
        //then we add a confirmation dialog to the
        //linkbutton in row 3.
        //Remember that we've hidden row zero 
        //that's why the Delete row is number three.
        DataGridHelper.AddConfirm(dgPersons, 3, 
              "Do you wish to delete this person?");
    }
    
    //if the user wants to add mouseovers
    if(chkAddJavascriptMouseovers.Checked)
    {
        //add the mouseover and mouseout attributes
        //and link them to to the javascript 
        //function "changeStyle()"
        DataGridHelper.AddAttributesToCells(dgPersons, 
                "onmouseover", "changeStyle(event);");
        DataGridHelper.AddAttributesToCells(dgPersons, 
                 "onmouseout", "changeStyle(event);");
        //using the event to make the javascript cross-browser
        //you can add any code you like with 
        //the "AddAttributesToCells" method.
    }
    
    //make sure all columns in the DataGrid 
    //are one third of the width
    DataGridHelper.AddAttributesToCells(dgPersons,"width", "33%");
}
关注点
JavaScript
您可以将您自己的或他人的 JavaScript 代码与 DataGridHelper 类一起使用。我在这里包含了我一个更有趣的 JavaScript 代码,以防您将来某时会用到。我会在鼠标悬停在表格对象的单元格上时切换它们的 CSS 类名。

这取代了直接更改颜色、大小等。通过使用这种方法,您可以在鼠标离开单元格时将其恢复到原始状态,因为我只在类名前后添加 "_hover" 后缀。
因为我们有两个交替的行类型 "Item" 和 "AlternatingItem",所以我们不能简单地将行的背景颜色重置为预定义颜色,因为这样会让行在鼠标移出后看起来一样。
请查看并判断是否喜欢。
更新:这是一个改进版本,它使用跨浏览器脚本来访问 IE 或 FireFox 的事件模型。
<script language="javascript">
//////////////////////////////////////////////////
//        CHANGESTYLE - by Jakob Lund Krarup        //
//////////////////////////////////////////////////
/*This method will change the CSS class name
of an HTML item.
The name gets the text "_hover" appended 
when the mouse moves over the item,
and the name has the text "_hover" removed
from the class name when the mouse moves out again.
CROSSBROWSER:
Made this work with FireFox after reading:
http://www.oreillynet.com/pub/a/javascript/synd/2001/09/25/event_models.html?page=2
*/
function changeStyle(evt)
{
    //Crossbrowser - get the event as a parameter (FireFox)
    //or as the windows event (IE)
    var theEvent =  evt || window.event;
    //Crossbrowser - get the HTML element that fired this event
    //as either target (FireFox) or srcElement (IE)
    var theEventSource = theEvent.target || theEvent.srcElement;
                
    //according to the event type
    //...switch the CSS class of the element
    switch(theEvent.type)
    {
        //if the event that invoked this method
        //was a mouseover event
        case "mouseover" :
            //then we add "_hover" to the class name
            theEventSource.className  += "_hover";
            break;
                        
        //otherwise - if this was a mouseout event...
        case "mouseout"  : 
            //then we remove the "_hover" from the class name    
            theEventSource.className = 
                theEventSource.className.replace("_hover", "");
    }
}
</script>
这允许我们定义如下的 CSS 类,它们可以与 DataGrid 的单元格一起使用。
.Item_cell {
    background-color: Cornflowerblue;}
    
.Item_cell_hover {
    background-color: red;
    font-weight:bold;
    color: White;}
高级 - IHttpModule 接口实现(版本 1.2)
此实现使得 DataGridHelper 类能够将 CSS 应用于 Web 项目中所有“传出”的 DataGrid 控件,而无需您为每个控件编写代码。如果您只想使用 DataGridHelper 类并在需要时调用其方法,则可以跳过最后一部分。要使其正常工作,您必须将 HttpModuleDataGridHelper.dll 文件添加到 Web 应用程序的 BIN 文件夹中,并在 web.config 文件的 </system.web> 部分添加以下行:
web.config 添加项
    <httpModules>
      <add name="DataGridHelperModule"
        type="AddCssToDataGridSample.DataGridHelper, HttpModuleDataGridHelper" />
     </httpModules>
如果您不想手动编辑 web.config,只需在您的 Web 应用程序文件夹中运行 此工具。它将为您更新 web.config 文件,并从 Internet 下载 DataGridHelper.dll 文件到 BIN 文件夹。我提交给 The Code Project 的下一篇文章将是关于这个安装程序工具以及它是如何制作的。
(如果您想了解更多关于编写 HttpModule 的知识,我建议您阅读 这篇文章。)
结束语
我非常喜欢每周的 CSDN 时事通讯。我是一名忠实读者,希望我的贡献能为社区带来一些回馈 : )
在您急于去键盘告诉我,我只需为我的 DataGrid 添加一个 CSS 类,然后使用 ".datagrid td" 代码定义 TDTR
我只是认为,如果所有单元格和行都有 CSS 类,那么调整任何客户端脚本、CSS 或 DHTML 会更容易。
诚挚的问候 - Jake (Jakob Lund Krarup)。
历史
- 1.2 
- 为 DataGridHelper类添加了IHttpModule接口的实现。因此,除了像以前一样工作之外,您现在还可以实现 CSS 的添加,而无需编写代码 : )
 
- 为 
- 1.1 
- 根据 R.vd.B 的建议 - 我已更改 AddCssToDataGrid,使其也能为DataGrid中的按钮添加 CSS 类。
- Scott (bisc0tti) 注意到,在 FireFox 中添加 CSS 时,删除确认不起作用。这与 DataGridHelper类无关,而是我使用的示例 JavaScript 中缺少跨浏览器编程。
- 该脚本现在已更新为可以跨浏览器工作了 : )。
- 感谢 Scott(以及 SirTrolle,他建立了与 CSS 的联系)!: )
 
- 根据 R.vd.B 的建议 - 我已更改 



 在线试用
在线试用