I have a GridView which I Bind a DataSource to it from a SQL Database, the grid has a column with a checkbox in it so I can "select" a few Item in it (Rows actually). What I want here is to do some updates on the Item in each selected rows, but after some search I can't find how to access the Item in a Row, I though DataItem would work, but it's giving me a Null.
我有一个GridView,我从SQL数据库绑定了一个DataSource,网格有一个带有复选框的列,所以我可以“选择”其中的一些项目(实际上是行)。我想要的是在每个选定的行中对Item进行一些更新,但在一些搜索后我找不到如何访问一行中的Item,虽然DataItem可以工作,但它给了我一个Null。
Edit: To make it short, I have a GridView which is built from a DataSource, so basically, each rows represent an Object, when I have a checkbox checked in one of the rows, I want to be able to grab the Object related to that Row, what is the easiest way to achieve that?
编辑:为了简短起见,我有一个从DataSource构建的GridView,所以基本上,每行代表一个Object,当我在其中一行中选中了一个复选框时,我希望能够获取与之相关的Object那一行,最简单的方法是什么?
The DataBinding on Page_Load:
Page_Load上的DataBinding:
if (!Page.IsPostBack) { gvUnusedAccessories.DataSource = currentContext.Items.OfType<Accessory>().Where(ac => ac.Item_Parent_Id == ((PhoneLine)currentItem).Parent.Item_Id); gvUnusedAccessories.AutoGenerateColumns = false; gvUnusedAccessories.DataBind(); }
The event when I press the Update Button, It actually browse the rows and if the row has a checked box it's gonna do the update:
我按下更新按钮的事件,它实际上浏览行,如果行有一个复选框,它将进行更新:
protected void btnAddToMobile_Click(object sender, EventArgs e) { foreach (GridViewRow row in gvUnusedAccessories.Rows) { if(((CheckBox)row.FindControl("chkSelect")).Checked) { ((Accessory)row.DataItem).PhoneLine_Id = currentItem.Item_Id; } } }
And here's my GridView in the .aspx :
这是我在.aspx中的GridView:
<asp:GridView ID="gvUnusedAccessories" runat="server">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate >
<asp:CheckBox ID="chkSelect" runat="server" AutoPostBack="True"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Item_Id" HeaderText="ID" ReadOnly="True"/>
<asp:BoundField DataField="Item_Name" HeaderText="Name" ReadOnly="True"/>
<asp:BoundField DataField="AccessoryModel" HeaderText="Modèle" ReadOnly="True"/>
<asp:BoundField DataField="AccessoryBrand" HeaderText="Marque" ReadOnly="True"/>
</Columns>
</asp:GridView>
Any hint on how to access the Object contained inside a Row? I know I could actually get the ID and then do a SQL request to my DB, but it seems to be a bit heavy and there must be a better solution.
有关如何访问Row中包含的Object的任何提示?我知道我实际上可以获得ID,然后向我的数据库发出SQL请求,但它看起来有点沉重,必须有一个更好的解决方案。
2 个解决方案
#1
3
Unless you're storing the DataSource in ViewState or session once the databinding is done you lose the data source. The DataItem will always be null unless you do this. Because of this I often find myself storing the data source in view state. Of course this means your page size is going to get bigger. The other option as you stated is to requery the data source with some sort of primary key. Depending on your needs I can't say which option is better. I tend to lean towards view state rather than a second DB call since that can be an expensive call to make
除非您在数据绑定完成后将数据源存储在ViewState或会话中,否则会丢失数据源。除非您这样做,否则DataItem将始终为null。因此,我经常发现自己将数据源存储在视图状态。当然,这意味着您的页面大小会变得更大。您所说的另一个选项是使用某种主键重新查询数据源。根据您的需要,我不能说哪个选项更好。我倾向于倾向于视图状态而不是第二个DB调用,因为这可能是一个昂贵的调用
#2
2
Given that you have the AutoPostBack
set to true on your asp:checkbox
you must update the row as you set the checkbox
假设您在asp:复选框上将AutoPostBack设置为true,则必须在设置复选框时更新该行
So I would suggest you you set event OnCheckedChanged="chkStatus_OnCheckedChanged"
on asp:checkbox
called chkSelect
and then you can only update the selected row and don't have to iterate over the enitre grid.
所以我建议你在asp:复选框上设置事件OnCheckedChanged =“chkStatus_OnCheckedChanged”chkSelect,然后你只能更新所选择的行,而不必迭代enitre网格。
Here is an example how you can get the row items of the selected checkbox
下面是一个如何获取所选复选框的行项的示例
public void chkStatus_OnCheckedChanged(object sender, EventArgs e)
{
CheckBox chkStatus = (CheckBox)sender;
//now grab the row that you want to update
GridViewRow row = (GridViewRow)chkStatus.NamingContainer;
string cid = row.Cells[1].Text;
bool status = chkStatus.Checked;
//now you can do you sql update here
}
#1
3
Unless you're storing the DataSource in ViewState or session once the databinding is done you lose the data source. The DataItem will always be null unless you do this. Because of this I often find myself storing the data source in view state. Of course this means your page size is going to get bigger. The other option as you stated is to requery the data source with some sort of primary key. Depending on your needs I can't say which option is better. I tend to lean towards view state rather than a second DB call since that can be an expensive call to make
除非您在数据绑定完成后将数据源存储在ViewState或会话中,否则会丢失数据源。除非您这样做,否则DataItem将始终为null。因此,我经常发现自己将数据源存储在视图状态。当然,这意味着您的页面大小会变得更大。您所说的另一个选项是使用某种主键重新查询数据源。根据您的需要,我不能说哪个选项更好。我倾向于倾向于视图状态而不是第二个DB调用,因为这可能是一个昂贵的调用
#2
2
Given that you have the AutoPostBack
set to true on your asp:checkbox
you must update the row as you set the checkbox
假设您在asp:复选框上将AutoPostBack设置为true,则必须在设置复选框时更新该行
So I would suggest you you set event OnCheckedChanged="chkStatus_OnCheckedChanged"
on asp:checkbox
called chkSelect
and then you can only update the selected row and don't have to iterate over the enitre grid.
所以我建议你在asp:复选框上设置事件OnCheckedChanged =“chkStatus_OnCheckedChanged”chkSelect,然后你只能更新所选择的行,而不必迭代enitre网格。
Here is an example how you can get the row items of the selected checkbox
下面是一个如何获取所选复选框的行项的示例
public void chkStatus_OnCheckedChanged(object sender, EventArgs e)
{
CheckBox chkStatus = (CheckBox)sender;
//now grab the row that you want to update
GridViewRow row = (GridViewRow)chkStatus.NamingContainer;
string cid = row.Cells[1].Text;
bool status = chkStatus.Checked;
//now you can do you sql update here
}