问题描述
如何通过单击编辑按钮使所有行单元格都可编辑。 以下是截取的代码。任何帮助,将不胜感激。单击 btnEdit_Click 事件时,我希望 radgrid 行单元格可编辑,以便使用可以更新现有数据。我不想为 radgrid 中的每一行添加内联编辑按钮,而是在单个编辑按钮上,所有行单元格都应根据其数据类型进行编辑。
<asp:ImageButton runat="server" ID="btnEdit" ImageUrl="~/images/Buttons/Edit.gif"
OnClick="btnEdit_Click" />
<radG:RadGrid ID="GrdAction" runat="server" AllowPaging="True" Width="100%" EnableAJAXLoadingTemplate="true"
CellPadding="1" CellSpacing="1" AllowSorting="True" ShowHeader="false" OnNeedDataSource="Grd_View_NeedDataSource"
OnDetailTableDataBind="Grd_View_DetailTableDataBind" PageSize="11" MasterTableView-GroupsDefaultExpanded="true"
OnPreRender="Grd_View_PreRender" AllowmultirowSelection="true" MasterTableView-EditFormSettings-EditColumn-AutopostBackOnFilter="false"
Skin="Glassy" AllowmultirowEdit="true">
<MasterTableView AutoGenerateColumns="False" HierarchyDefaultExpanded="true">
<AlternatingItemStyle CssClass="GridView-GroupHeaderItemStyle" />
<Columns>
<radG:GridTemplateColumn UniqueName="TemplateColumn" SortExpression="VSGroupBy">
<ItemTemplate>
<asp:Label ID="lblStatus" Visible="false" runat="server" Text='<%# DataBinder.Eval(Container.DataItem,FirsTGROUP).ToString() %>'> </asp:Label>
<asp:Label ID="lblStatus1" runat="server" Text='<%# GetGroupBy(DataBinder.Eval(Container.DataItem,FirsTGROUP).ToString()) %>' />
<asp:Label ID="lblcnt" runat="server" Text='' />
</ItemTemplate>
<ItemStyle Width="100%" />
</radG:GridTemplateColumn>
</Columns>
<ExpandCollapseColumn>
<HeaderStyle Width="19px" />
</ExpandCollapseColumn>
<DetailTables>
<radG:GridTableView Width="100%" runat="server" AutoGenerateColumns="False" ShowHeader="True"
HierarchyLoadMode="ServerBind">
<HeaderStyle CssClass="GridView-HeaderStyle" Width="10%" />
<Columns>
<radG:GridTemplateColumn HeaderText="Header1" SortExpression="Header1">
<ItemTemplate>
<asp:Label ID="lblItem1" runat="server" Text='<%# Eval("RootCause").ToString()+ " " %>'></asp:Label>
</ItemTemplate>
<ItemStyle VerticalAlign="Top" />
<HeaderStyle Width="22%" Wrap="True" />
</radG:GridTemplateColumn>
<radG:GridTemplateColumn HeaderText="header2" SortExpression="" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Label ID="lblAgree" runat="server" CssClass='<%# Eval("lblitem2").ToString()=="N"?"AgreeStyles": ""%>' Text='<%# Eval("lblitem2").ToString()+ " " %>'></asp:Label>
</ItemTemplate>
<ItemStyle VerticalAlign="Top" />
<HeaderStyle Width="3%" Wrap="True" />
</radG:GridTemplateColumn>
<radG:GridTemplateColumn HeaderText="header3" SortExpression="What">
<ItemTemplate>
<asp:Label ID="lblitem3" runat="server" Text='<%# UIHelper.TextArea2HTML(Eval("lblitem3").ToString())+ " " %>'></asp:Label>
</ItemTemplate>
<ItemStyle VerticalAlign="Top" />
<HeaderStyle Width="15%" Wrap="True" />
</radG:GridTemplateColumn>
</Columns>
<PagerStyle Mode="NumericPages" Position="TopAndBottom" />
<EditFormSettings>
<EditColumn UniqueName="EditCommandColumn">
</EditColumn>
</EditFormSettings>
<AlternatingItemStyle CssClass="GridView-ItemStyle" />
<GroupHeaderItemStyle CssClass="GridView-GroupHeaderItemStyle" />
<ExpandCollapseColumn ButtonType="ImageButton" UniqueName="ExpandColumn" Visible="False">
<HeaderStyle Width="19px" />
</ExpandCollapseColumn>
<ItemStyle CssClass="GridView-ItemStyle" />
<RowIndicatorColumn UniqueName="RowIndicator" Visible="False">
<HeaderStyle Width="20px" />
</RowIndicatorColumn>
<norecordstemplate>
There is no document to display
</norecordstemplate>
</radG:GridTableView>
</DetailTables>
<norecordstemplate>
There is no Actions to display
</norecordstemplate>
<ExpandCollapseColumn Visible="False">
<HeaderStyle Width="19px" />
</ExpandCollapseColumn>
<RowIndicatorColumn Visible="False">
<HeaderStyle Width="20px" />
</RowIndicatorColumn>
<ItemStyle CssClass="GridView-GroupHeaderItemStyle" />
</MasterTableView>
<PagerStyle Mode="NumericPages" PageButtonCount="20" />
<HeaderStyle CssClass="GridView-HeaderStyle" />
<GroupHeaderItemStyle CssClass="GridView-GroupHeaderItemStyle" />
<ItemStyle CssClass="GridView-GroupHeaderItemStyle" />
<AlternatingItemStyle CssClass="GridView-GroupHeaderItemStyle" />
<PagerStyle Mode="NumericPages" Position="TopAndBottom" PageButtonCount="20" />
<FilterMenu HoverBackColor="LightSteelBlue" HoverBorderColor="Navy" NotSelectedImageUrl="~/RadControls/Grid/Skins/Default/NotSelectedMenu.gif"
SelectColumnBackColor="Control" SelectedImageUrl="~/RadControls/Grid/Skins/Default/SelectedMenu.gif"
TextColumnBackColor="Window"></FilterMenu>
<ClientSettings>
<Selecting AllowRowSelect="true"></Selecting>
</ClientSettings>
</radG:RadGrid>
解决方法
好的,几个问题。 您(看起来)正在使用数据寻呼机 - 这会使事情变得相当复杂。
接下来,您使用 radgrid - 所以,这里的大部分海报 - 他们很可能没有答案。
但是,我确实认为抛出一个网格的想法 - 让用户编辑,然后为所有编辑保存一个 SINGLE 非常有意义。事实上,考虑到用户界面,那么真的不需要编辑按钮。您真正需要/想要的只是一个保存按钮,然后说取消/撤消编辑。
上面的一个非常巧妙的技巧?只需保留数据源。一旦你这样做了?
然后您允许用户编辑网格 -(无需代码)。
然后在保存时,您将网格编辑移回数据表,然后在 ONE NICE EASY 更新中,将数据表发送回数据库。这不仅产生了非常少的代码,而且还为用户提供了一个非常漂亮且整洁的用户界面。
所以,让我们使用 GridView。事实上,我经常建议使用列表视图。 为什么? 好吧,对于 gridview(和旧的 datagrid),对于您放入的每个列控件,您必须将该标准控件放在“模板”标签内 - 因此您需要更多(杂乱)标记。
但是,让我们用一个简单的 gridview 来做到这一点,正如你所看到的,这不仅很容易,而且我们还使用 .net 来创建更新语句,我们“利用”内置系统来完成所有工作肮脏的工作。
所以,假设我们有这个网格:
<style> .borderhide input {border:none}</style>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID"
cssclass="table table-hover borderhide">
<Columns>
<asp:TemplateField HeaderText ="First Name">
<ItemTemplate>
<asp:TextBox ID="txtFirst" runat="server" Text = '<%# Eval("FirstName") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Last Name">
<ItemTemplate>
<asp:TextBox ID="txtLast" runat="server" Text = '<%# Eval("LastName") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="City">
<ItemTemplate>
<asp:TextBox ID="txtCity" runat="server" Text = '<%# Eval("City") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Active">
<ItemTemplate>
<asp:CheckBox ID="Active" runat="server" Checked = '<%# Eval("Active") %>'></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="cmdSave" runat="server" Text="Save" CssClass="btn-primary" OnClick="cmdSave_Click1" />
<asp:Button ID="cmdAdd" runat="server" Text="Add Row" CssClass="btn-primary" style="margin-left:20px"/>
<br />
好的,没有太多标记。
所以,现在这是我们填充网格的代码:
private DataTable rstPeople = new DataTable();
protected void Page_Load(object sender,EventArgs e)
{
if (!IsPostBack)
{
LoadGrid();
ViewState["MyTable"] = rstPeople;
Session["test"] = "hello";
}
else
rstPeople = (DataTable)ViewState["MyTable"];
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from People",new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
rstPeople.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstPeople;
GridView1.DataBind();
}
}
好的,但请注意我们如何加载网格,但还要保存(保留)数据表。
所以,我们现在有了这个:
好的,现在您可以随意切换 - 编辑 - 感觉几乎就像一个电子表格。
现在,这里是保存按钮,可以一次性将整个编辑集发送回数据库:
protected void cmdSave_Click1(object sender,EventArgs e)
{
// pull grid rows back to table.
foreach (GridViewRow rRow in GridView1.Rows)
{
int RecordPtr = rRow.RowIndex;
DataRow OneDataRow;
OneDataRow = rstPeople.Rows[RecordPtr];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["City"] = ((TextBox)rRow.FindControl("txtCity")).Text;
OneDataRow["Active"] = ((CheckBox)rRow.FindControl("Active")).Checked;
}
// now send table back to database with updates
string strSQL = "SELECT ID,FirstName,LastName,City,Active from People WHERE ID = 0";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
SqlDataAdapter daupdate = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder cmdBuild = new SqlCommandBuilder(daupdate);
daupdate.Update(rstPeople);
}
}
因此,我们将网格发送回表格。 然后我们将表发送回数据库。
如您所见,这种方法节省了大量代码。
这里唯一的附加问题?
您正在使用数据分页器。但是,这意味着对于每个页面导航,从该持久表重新绑定网格 - 不要每次都从数据库重新加载数据表。但是,数据分页器使这非常复杂,因为在页面导航中,理论上我们必须将该显示页面上的更改保存回表(我们不需要将表发送回数据库,但我们确实需要将可能的更改从网格发送回表。因此,由于导航来自该表,所以这应该可以工作 - 我们还没有点击保存将持久化表发送回数据库。
并注意 gridrow(和大多数控件)可以返回当前页面索引或行的整体索引位置。所以,我没有使用数据分页器完成上述工作,但应该可以工作。
并没有真正需要一个编辑按钮 - 我的意思是,无论如何编辑会做什么?我不认为这是必需的 - 反正只是把简单的 UI 弄乱了。
当然,我们应该提供取消/撤消。只需再次调用 LoadGrid,然后从数据库重新加载网格即可。
上述方法应该适用于 radGrid - 但我从未使用过它。
如前所述,上述想法适用于 GridView、listview 甚至更旧的数据网格。
我在这 3 个选项中的首选实际上是列表视图,因为如前所述,您不必在每个普通的 jane asp.net 控件(例如文本框,或者如上所述也是一个检查)周围放置凌乱的模板标签框)。
和上面的添加行代码,允许添加新行?
我们有这个:
protected void cmdAdd_Click(object sender,EventArgs e)
{
// add a new row to the grid
DataRow OneRow = rstPeople.Rows.Add();
GridView1.DataSource = rstPeople;
GridView1.DataBind();
}
再一次 - 真的很简单!!!再次很容易,因为我们对表格进行操作,然后只需重新绑定网格。