65.9K
CodeProject 正在变化。 阅读更多。
Home

DataGridHelper工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (25投票s)

2005年6月14日

CPOL

8分钟阅读

viewsIcon

178335

downloadIcon

4200

一个辅助类,用于方便地为 ASP.NET DataGrid 组件添加 CSS 类和确认对话框。

在线试用

Sample image of the tool in action

引言

当使用 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 数据之前调用此方法。

原因是我找不到除了附加到 DataGridItemDataBound 事件之外的任何其他方法来访问 DataGrid 的 Header、Footer、Pager 等行。

我尝试遍历 DataGrid.Items,但这只能访问 ItemAlternatingItemSelectedItemEditItem 项。

这是核心方法

//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 类,使其在视觉上呈现不同的外观,具体取决于其类。
  • 为了避免在示例项目中包含数据库,我创建了一个类型化数据集,将数据库表加载到其中,并使用 DataSetWriteXml() 方法将其写入磁盘。这样我就可以(并且确实)使用 ReadXml() 方法将数据重新加载到 DataSet 中。
  • 我在页面上有一个名为 dgPersonsDataGrid。使用 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" 代码定义 TD 代码或 TR 代码的样式即可,我想告诉您,我知道 ; )。

我只是认为,如果所有单元格和行都有 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 的联系)!: )
© . All rights reserved.