I have a GridView that I use to show my users the result of a search. I want to allow them to choose which columns are shown on the GridView when performing their search. Simple enough, yes? I wanted to try doing this using just databinding, no events. Unfortunately, my code fails to update the GridView using checkboxes bound to the column's Visible property. The state of the chechboxes changes, but the Visible property of the columns does not.
Snippet of Search.aspx:
<myControl:FacultyGridView ID="FacultyGridView1" runat="server" />
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Text='<%# Eval("HeaderText") %>' Checked='<%# Bind("Visible") %>' AutoPostBack=true/></ItemTemplate>
</asp:Repeater>
Code-behind snippet in Search.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
Repeater1.DataSource = FacultyGridView1.GridView.Columns;
Repeater1.DataBind();
}
To be clear, the GridView is exposed as a public property of a user control named FacultyGridView. Relevant snippet of FacultyGridView.ascx:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
AllowPaging="True" AllowSorting="True" PageSize="25">
<PagerSettings Mode="NumericFirstLast" Position="TopAndBottom" />
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" ReadOnly="True" SortExpression="Name" />
<asp:TemplateField HeaderText="University" SortExpression="UniversityID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("University.Name") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Division">
<ItemTemplate>
<asp:Repeater ID="Repeater1" runat="server" DataSource='<%# Eval("DivisionMemberships") %>'>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("Division.Name") %>'></asp:Label>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Title" HeaderText="Title" ReadOnly="True" SortExpression="Title" />
<asp:TemplateField HeaderText="Research Type">
<ItemTemplate>
<asp:Repeater ID="Repeater1" runat="server" DataSource='<%# Eval("ResearchTypeMappings") %>'>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ResearchType.Name") %>'></asp:Label>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Expertise" HeaderText="Expertise" ReadOnly="True" SortExpression="Expertise" />
<asp:HyperLinkField DataNavigateUrlFields="Website" DataTextField="Website" HeaderText="Website"
SortExpression="Website" />
<asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
<asp:TemplateField HeaderText="Email Address" SortExpression="EmailAddress">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("EmailAddress", "mailto:{0}") %>'
Text='<%# Eval("EmailAddress") %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Finally, I should mention that the GridView is bound by a Button on the page, but I am not getting updates to the Visible property whether I play with the checkboxes before or after databinding. Furthermore, I have not seen my desired behavior when binding the repeater only on the first Page_Load() using if(!IsPostBack), nor by not using Checkbox.AutoPostback true or false. Any clue as to what I'm doing wrong? I expect it to be something simple, but I'm a bit green here.
As a note: I know how to do this easily with events, but I want to do it with databinding as a learning exercise.
Probably because every time the grid is bound to the data, the column & settings are recreated (with-out your changes).
Related
Having an asp:GridView, when I put it into edit mode by setting EditIndex, I also need to update its data using the DataSource property and call DataBind like this:
protected void GrdFoo_OnRowEditing(object sender, GridViewEditEventArgs e)
{
grdFoo.EditIndex = e.NewEditIndex;
grdFoo.DataSource = DataBase.GetFoos();
grdFoo.DataBind();
}
Now, if the database contents was changed since I was populating the gridview first, how can I be sure I will edit the correct row?
edit
I got the suggestion to use OnRowDataBound. I am using a command field to trigger GrdFoo_OnRowEditing. Is the use of OnRowDataBound still a good idea?
Here is how I use the CommandField (aspx):
<asp:GridView ID="grdFoo" runat="server"
OnRowEditing="GrdFoo_OnRowEditing"
OnRowCancelingEdit="GrdFoo_OnRowCancelingEdit"
OnRowUpdating="GrdFoo_OnRowUpdating"
OnRowDeleting="GrdFoo_OnRowDeleting"
DataKeyNames="ID">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label Text='<%#Eval("Name") %>' runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtName" Text='<%#Eval("Name") %>' runat="server"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Email">
<ItemTemplate>
<asp:Label Text='<%#Eval("Email") %>' runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtEmail" Text='<%#Eval("Email") %>' runat="server"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True"
ShowDeleteButton="True" buttontype="Image"
DeleteImageUrl="delete.png"
EditImageUrl="edit.png"
CancelImageUrl="cancel.png"
UpdateImageUrl="save.png"/>
</Columns>
</asp:GridView>
I'm binding an array to GridView. Below is my template field and it doesn't fire RowUpdating when I click on update.
<asp:TemplateField HeaderText="Role">
<EditItemTemplate>
<asp:TextBox runat="server" Text='<%# Container.DataItem.ToString() %>' ID="txtEditRole"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<%# Container.DataItem.ToString() %>
</ItemTemplate>
</asp:TemplateField>
This happened after making the field to TempleteField. Earlier the field was like below.
<asp:BoundField DataField="!" HeaderText="Role" />
Make sure you specify OnRowUpdating="gv_RowUpdating" event and also change FieldName in <%#Eval("Role") %>, see this example:
.aspx page
<asp:GridView ID="gv" runat="server" DataKeyNames="Id" AutoGenerateColumns="false" OnRowEditing="gv_RowEditing"
OnRowUpdating="gv_RowUpdating" OnRowCancelingEdit="gv_RowCancelingEdit" OnRowCommand="gv_RowCommand" OnRowDeleting="gv_RowDeleting">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:LinkButton ID="lbtnUpdate" runat="server" CommandName="Update" Text="Update" />
<asp:LinkButton ID="lbtnCancel" runat="server" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="lbtnEdit" runat="server" CommandName="Edit" Text="Edit" />
<asp:LinkButton ID="lbtnDelete" runat="server" CommandName="Delete" Text="Delete" OnClientClick="return confirm('Are you sure you want to delete this record?')" CausesValidation="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Role">
<EditItemTemplate>
<asp:TextBox ID="txtEditRole" runat="server" Text='<%#Eval("Role") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblRole" runat="server" Text='<%#Eval("Role") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
.aspx.cs
protected void gv_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//your code here..
}
To check complete article, checkout insert, update, delete gridview data example in asp.net.
I've dropdown to language based on language selection change master page.
Where as I've gridview , this will bind with data based on language .
When i change language textbox value in gridview is not changing other than that remaining control values are changing .
Here is my Code of gridview
<asp:TemplateField HeaderText="<%$ Resources:AFRResources, Status %>" ItemStyle-CssClass="gridLanguage-status"
SortExpression="STATUS" ItemStyle-HorizontalAlign="Center" HeaderStyle-ForeColor="White">
<ItemTemplate>
<asp:Label ID="lblActive" runat="server" Text='<%# Bind("ACTIVE") %>'></asp:Label>
</ItemTemplate>
<HeaderStyle CssClass="gridLanguage-status" ForeColor="White" />
<ItemStyle CssClass="gridLanguage-status" HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="<%$ Resources:AFRResources, SeqNo %>" HeaderStyle-CssClass="gridViolation-status"
ItemStyle-CssClass="gridViolation-status" ItemStyle-HorizontalAlign="Center"
HeaderStyle-ForeColor="White" SortExpression="STATUS">
<ItemTemplate>
<asp:Label ID="lblSeqno" runat="server" Text='<%# Bind("SEQUENCENO") %>'></asp:Label>
<asp:TextBox ID="txtSeqNo" runat="server" Width="40%" Text='<%# Bind("SEQUENCENO") %>'
onchange="SetValue()" MaxLength="4" ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
but you have to refresh your gridview i mean you could have a method that receives as parameter the selection from your dropdownlist you could maybe use the event SelectedIndexChanged
I have one radio button in gridview itemplate field. But when I am selecting the radiobutton i am unable to get the id of that row. So that based on that id textbox value will be autopopulated.
enter code here
<asp:GridView ID="gvItem" SkinID="GridView" runat="server" OnRowDataBound="gvItem_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="" Visible="false">
<ItemTemplate>
<%#Container.DataItemIndex %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="rbtnQuantity" runat="server" AutoPostBack="true" OnCheckedChanged="rbtnQuantity_CheckedChanged" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" Width="20px" />
</asp:TemplateField>
<%--1--%>
<asp:TemplateField HeaderText="ID" SortExpression="ID">
<ItemTemplate>
<asp:Label ID="lblID" runat="server" Text=' <%# Eval("ID")%>'></asp:Label>
</ItemTemplate>
<ItemStyle Width="90px" />
</asp:TemplateField>
<%--2--%>
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<ItemTemplate>
<asp:Label ID="lblItemName" runat="server" Text='<%# Eval("Name")%>'></asp:Label>
</ItemTemplate>
<ItemStyle Width="140px" />
</asp:TemplateField>
</Columns>
</asp:GridView>
You can try on the radiobutton click event to look for sender.parent.findcontrol("lblID").
this would be on the code-behind and for vb.net it would look like this:
Dim rowID as String = CType(CType(sender, RadioButton).Parent.FindControl("lblID"),Label).Text
I would like to sort my GridView by clicking on the column's header. So far I declared a SPDataSource
<SharePoint:SPDataSource
runat="server"
ID="SPdsInventarGrid"
DataSourceMode="List"
UseInternalName="true"
Scope="Recursive"
SelectCommand="<View><Query><Where><Or><Neq><FieldRef Name='EBS_x002e_CN_x002e_Inventar_x00210' /><Value Type='Text'>Open</Value></Neq><IsNull><FieldRef Name='EBS_x002e_CN_x002e_Inventar_x0028' /></IsNull></Or></Where></Query><ViewFields><FieldRef Name='Title'/><FieldRef Name='ID'/><FieldRef Name='EBS_x002e_CN_x002e_Inventar_x0028'/><FieldRef Name='EBS_x002e_CN_x002e_Inventar_x00210'/><FieldRef </ViewFields></View>">
<SelectParameters>
<asp:Parameter Name="ListName" DefaultValue="Inventar" />
</SelectParameters>
</SharePoint:SPDataSource>
Then I created my grid, based on the datasource
<asp:GridView Visible="true" Width="100%"
ID="gvInventar"
AutoGenerateColumns="false" runat="server" CellPadding="2" AllowPaging="false" AllowSorting="true" OnSorted="gvInventar_Sorted" OnSorting="gvInventar_Sorting" GridLines="None" DataSourceID="SPdsInventarGrid" OnRowCommand="gvInventar_RowCommand">
<Columns>
<asp:CommandField ButtonType="Image" ShowEditButton="true" EditImageUrl="/_layouts/images/edit.gif" UpdateImageUrl="/_layouts/images/save.gif" CancelImageUrl="/_layouts/images/delete.gif" />
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label Text='<%# Bind("ID") %>' runat="server" ID="lblIdProduct"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title" >
<ItemTemplate>
<asp:Label Text='<%# Bind("Title") %>' runat="server" ID="lblTitleProduct" ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Product" SortExpression="Product">
<ItemTemplate>
<asp:Label Text='<%# Bind("EBS_x002e_CN_x002e_Inventar_x0028") %>' runat="server" ID="lblProduct" "></asp:Label>
</ItemTemplate>
</Columns>
</asp:GridView>
Now, I have this function where I wanted to get the current Query as a string and add <OrderBy>(my field) before <Query> but i get an error saying that the DataSource has been already declared (which is true because i want to be declared in asp)
protected void gvInventar_Sorting(object sender, GridViewSortEventArgs e)
{
SPQuery q = new SPQuery();
q.Query = SPdsInventarGrid.SelectCommand;
switch (e.SortExpression)
{
case "Product":
if (e.SortDirection == SortDirection.Ascending)
{
gvInventar.DataSource = q.Query;
gvInventar.DataBind();
}
else
{
}
break;
}
}
Even though it's not working this way, I don't think modifying the Query is the solution.
Could anyone help me with this matter?
You don't need to write any custom code to sort the gridview by clicking the column headers, all you have to do is set the SortExpression property of the TemplateField to the required column name, e.g:
<Columns>
<asp:TemplateField HeaderText="ID" SortExpression="ID">
<ItemTemplate>
<asp:Label Text='<%# Bind("ID") %>' runat="server" ID="lblIdProduct" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title" SortExpression="Title">
<ItemTemplate>
<asp:Label Text='<%# Bind("Title") %>' runat="server" ID="lblTitleProduct" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Product" SortExpression="EBS_x002e_CN_x002e_Inventar_x0028">
<ItemTemplate>
<asp:Label Text='<%# Bind("EBS_x002e_CN_x002e_Inventar_x0028") %>' runat="server"
ID="lblProduct" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
Now you can sort on all 3 columns: