没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2005-01-04 09:51:00.000|阅读 1432 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
Update 操作
请注意,在图 2 中看不到可在图 1 中看到的 Delete 列。为了简化界面,我决定在任何行进入编辑模式时隐藏 Delete
列。并且因为有了以前提到的内置事件处理程序,所以此行为在 EditableGrid 类中是硬编码的。
update 操作是由以下三个事件执行的:
• EditCommand — 开始该操作并以编辑模式呈现行
• UpdateCommand — 保存所做的更改并还原默认用户界面
• CancelCommand — 取消所做的更改并还原以前的用户界面
用于 EditCommand 和 CancelCommand 的典型代码是能够方便地嵌入类中的传统 vanilla
代码。一般来说,此处没有真正需要在页面级解决的内容,但是有时情况也可能与您的特定实例有所不同。
“更新” 操作的应用程序特定的逻辑集中在 “更新命令” 事件中。除了保存任何更改以外,您应当还原网格的一致状态(取消编辑模式、还原 Delete
列和拒绝待定的更改),并确保所做的更改随后由用于显示的数据源反映出来。如果您像本例中那样使用缓存数据,则后面的一点至关重要。
public void OnUpdateCommand(Object sender, DataGridCommandEventArgs e)
{
// Clear edit mode
EditItemIndex = -1;
// Show/Hide DELETE column
ToggleDeleteColumn(true);
// Reject changes on the last row
RejectChanges = true;// internal member
// Update or insert data
if (MustInsertRow)// internal member
OnInsertData(e);
else
OnSaveData(e);
// Refresh view
OnUpdateView(EventArgs.Empty);
}
UpdateCommand 处理程序取消当前行的编辑模式,然后打开 Delete 列的可见性标志。此时,该表可能有一个待定的更改。因为 “更新命令”
事件会在两种情况(打算将所做的更改保存到现有的行中时;要插入新行时)下激发,所以条件窗体很有意义。内部成员 MustInsertRow 由
InsertNewRow 设置并由 DataSource 重置,它有助于确定是哪种情况。当代码处理完网格的状态之后,它激发两个连续事件 —
一个事件让页面保存或插入到物理数据源中,另一个事件刷新数据绑定。这就解释了为何 InsertData 和 SaveData 处理程序只能执行主要通过 SQL
语句来进行的物理更新。
InsertData 和 SaveData 事件处理程序的签名与 UpdateCommand 的相同。
public event DataGridCommandEventHandler SaveData;
protected virtual void OnSaveData(DataGridCommandEventArgs e)
{
if (SaveData != null)
SaveData(this, e);
}
public event DataGridCommandEventHandler InsertData;
protected virtual void OnInsertData(DataGridCommandEventArgs e)
{
if (InsertData != null)
InsertData(this, e);
}
在本文中讨论的示例代码中,设置了几个假设,其中一个就是假设网格的数据源是 “数据视图”
对象。这间接表示不支持自定义分页,或者,更确切地讲,必须仔细修改此代码才能处理这样的网格。这同样适用于排序。
所作的第二个重要假设是有关使用 SQL 语句进行更新的。
设计思路是,无论进行了什么样的更改,总是激发单个 SQL 语句以应用它。此处设计的 EditableGrid 不能正确地处理批更新。顺便提一句,在我的
Building Web Solutions with ASP.NET and ADO.NET
一书中,在介绍就地编辑时,更详细地讨论了对于网格使用批更新的优缺点。然而,如果您对使用批更新技术感兴趣,请给我发送电子邮件,我将在以后的专栏中介绍此主题。
由于您通过直接的 SQL 语句(或者数据源识别为直接语句的内容)进行更新,因此,“更新命令” 事件可以成功地命令拒绝任何更改。这就是批更新方案中的主要区别。
“保存数据” 和 “插入数据”
事件代表执行更新所必需的任务的子集。在执行该命令之后,这些处理程序必须确保网格可以访问和显示刷新数据。在这种情况下,必须更新数据的缓存副本。根据基础数据库架构(任何触发器或任何自动编号的字段),可以决定是完全重新读取还是基于每个字段更新缓存数据。
让我们花些时间来了解如何从网格的编辑模板来检索更新后的数据。我考虑使 EditableGrid 控件具有足够的智能,以便从单元格提取值,并将它们填充到
DataRow 对象中以充当事件数据。这个方法使得在批方案中更新代码变得微不足道。之所以决定让 ASP.NET
页负责提取数据,是因为这样您也可以透明地支持编辑模板。下面我将向您展示在不使用任何特殊模板时所必需的代码。
public void SaveData(Object sender, DataGridCommandEventArgs e)
{
StringBuilder sb = new StringBuilder("");
sb.Append("UPDATE Employees SET ");
sb.Append("firstname='{0}',");
sb.Append("lastname='{1}',");
sb.Append("title='{2}',");
sb.Append("country='{3}' ");
sb.Append("WHERE employeeid={4}");
String cmd = sb.ToString();
sb = null;
TextBox fName= (TextBox) e.Item.Cells[1].Controls[0];
TextBox lName= (TextBox) e.Item.Cells[2].Controls[0];
TextBox position = (TextBox) e.Item.Cells[3].Controls[0];
TextBox country= (TextBox) e.Item.Cells[4].Controls[0];
cmd = String.Format(cmd,
fName.Text, lName.Text,
position.Text, country.Text,
grid.DataKeys[e.Item.ItemIndex]);
// Executes the command
OleDbConnection conn = new OleDbConnection(m_connString);
OleDbCommand c = new OleDbCommand(cmd, conn);
c.Connection.Open();
c.ExecuteNonQuery();
c.Connection.Close();
// Re-read from the database and updates the cache
DataFromSourceToMemory();
}
要检索用户在文本框中输入的信息,使用 e.Item.Cells[n].Controls[0] 表达式,其中n 是该列的索引(从 0
开始)。请记住,DataGrid 的就地编辑功能允许您通过将 “只读” 属性设置为 true 来将列视为只读。
Delete 操作
Delete 操作的工作方式与 Insert 和 Update 操作大体相同。自动创建的列有一个命令名 Delete,在单击该按钮时会导致激发 ±
事件。内置的处理程序修复网格的界面,然后依次先后激发 DeleteData 和 UpdateView。
由于删除操作的入侵性比插入或更新操作的强,因此您可能希望使用某个客户端脚本代码,并要求用户在继续之前确认。我在 last month's column
的“对话栏”部分中讨论了该方法。在本月的源代码中,有一个如下图所示的实际实现。
图 3. 在删除之前确认
最终的优化
我提到过 EditableGrid 控件支持编辑模板。让我来证明这一结论。在示例代码的第 2 步,我使用该网格中一组稍有不同的列。
<columns>
<asp:boundcolumn runat="server" headertext="ID"
datafield="employeeid" readonly="true" />
<asp:templatecolumn runat="server" headertext="Name">
<itemtemplate>
<%# DataBinder.Eval(Container.DataItem, "lastname") + ", " +
DataBinder.Eval(Container.DataItem, "firstname") %>
</itemtemplate>
<edititemtemplate>
<asp:textbox runat="server" id="lName"
text='<%#DataBinder.Eval(Container.DataItem, "lastname")%>' />
<asp:textbox runat="server" id="fName"
text='<%#DataBinder.Eval(Container.DataItem, "firstname")%>' />
</edititemtemplate>
</asp:templatecolumn>
<asp:boundcolumn runat="server" headertext="Position"
datafield="title" />
<asp:boundcolumn runat="server" headertext="Country"
datafield="country" />
</columns>
正如您可以看到的那样,有一个模板列,它在单个字段中显示名和姓。此列的编辑模板(您必须指定能够编辑该列的编辑模板)由两个并排的文本框提供。无需在类中进行任何更改,即可获得图
4 中所示的示例。
图 4. 使用编辑模板
另一方面,在使用从文本框中检索更新的文本的方式时,编辑模板需要进行少许调整。现在,可以按名称检索模板中的控件。之所以可以并且建议这样做,是因为您知道控件的
ID。
TextBox fName= (TextBox) e.Item.FindControl("fName");
TextBox lName= (TextBox) e.Item.FindControl("lName");
TextBox position = (TextBox) e.Item.Cells[2].Controls[0];
TextBox country= (TextBox) e.Item.Cells[3].Controls[0];
在本月的源代码中,您将发现该类的 C# 源代码、两个示例 ASP.NET 页以及我用过的 Access
数据库。但是,您将找不到编译过的程序集。我提供了一个(非常)简单的批文件,您可以使用它,针对与 beta 2 及其更高版本兼容的任何版本的 .NET CLR,将该类编译成为可执行代码。
注 如果您在使下载正确运行时遇到问题,请检查下列步骤:
• 1.将 CS 类编译成为程序集。这可通过打开一个 DOS 框并运行 ZIP 中的 c.bat 批处理文件来完成,或者通过在 Visual Studio
中创建一个新的类库项目并将类文件添加到这个空白项目中来实现。
• 2.必须使程序集对于示例 ASPX 页可用。下载文件中包括的批处理文件将该 DLL 复制到 c:\inetpub\wwwroot\bin
文件夹中。如果您恰好有一个不同的路径,请对它进行修改。如果您创建一个虚拟目录,请确保将该 DLL 复制到虚拟文件夹的 BIN 子文件夹中,而不要复制到 Web
服务器根的 BIN 文件夹中。
• 3.根据 ASP.NET 安全设置,在与示例 Microsoft Access 数据库交互时,可能会遇到难以处理的 Updateable Query
错误。在这种情况下,请更改示例 .MDB 文件的安全设置。在“Windows 资源管理器”中选择该文件,显示属性,然后单击安全选项卡。接着,添加 \ASPNET
用户并确保它有权写入和修改该文件。
• 4.刷新 ASPX 页面。
对话栏:创建自定义模板
在上一个专栏中,您讨论了 Summary 网格组件。是否有机会创建或加载汇总行的自定义模板?这将允许在 ASPX 文件中(而非代码中)规定设计的规范。
使用汇总行的自定义模板无疑将是可能的。问题只是在于如何实现?或者,更准确地说,哪种方法最简单?我将在下面介绍几种可能的方法。
• 使用 pagelet: 可以修改应用程序的代码,使其动态加载 pagelet 控件(又称用户控件) — 即 ASCX 文件。ASCX 文件看上去像一个小型
Web 窗体,而且其中的大部分内容都是布局信息。可以使用 Page.LoadControl 来按名称加载 ASCX 文件,然后将它添加到
DataGridItem 对象的某个单元格的 Controls 集合中。
• 模板列:DataGrid 的所有列都是模板化列。使用 ASP.NET 标记和各处的一些代码定义每一列的 。您能够执行的操作就是将
块的结构分成两个截然不同且互斥的部分 — 一部分用于普通行,另一部分用于汇总行。为了确保一次只显示一行,可以处理控件的 “可见”
属性并将该属性与界定汇总行或普通行的条件绑定。
• 编写新控件:从 DataGrid 派生一个新类并添加一个新的模板属性。这允许您使用自定义的子标记、按照与输入列模板几乎相同的方式输入汇总行布局。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号