Hiding ItemTemplate in gridview - asp.net

I have this code in .aspx page
<gridview .....
<columns>
............
...........
<asp:templatefield Visible="true" headertext="Title" >
<edititemtemplate>
<asp:checkbox id="chkTitle" runat="server" />
</edititemtemplate>
</asp:templatefield>
<asp:commandfield buttontype="Link" edittext="Edit" showeditbutton="true"/>
</columns>
</gridview>
i only want to show the column when the user clicks on Edit button to edit the row.

In your GV Data Bound Event Handler (not row data bound):
For i As Integer = 0 To GridView1.Rows.Count - 1
If GridView1.EditIndex = -1 Then
GridView1.Rows(i).Cells(0).Visible = False
else
GridView1.Rows(i).Cells(0).Visible = true
end if
Next
If GridView1.EditIndex = -1 Then
GridView1.HeaderRow.Cells(0).Visible = False
End If
Source

Code such as GridView.Columns[9].Visible = false; should work - only thing is that grid data-bind must happen after this line. In case you are relying on the view-state for binding the grid in post-back scenarios then you may try putting GridView.DataBind() after you set the column visibility.
Yet another harder way is to set visibility at cell levels in RowDataBound event - see this article that is using this technique.

Related

Filter gridview with OnChecked Event

I have a gridview loaded from a database with a checkbox in the first column. What I want is that when clicking on any row the grid will be filtered to show only the rows in which the value of the second cell is the same as the one I clicked on (having the option to select more rows with that value). Removing the checks he would reload all the information again. I tried doing it using the OnChecked event, but due to AutoPostBack it filters but loses the value of the checkbox checked. What is the best way to do what I want? I hope I have been explicit. Thank you
asp:GridView ID="gridview" runat="server" AutoGenerateColumns="false" DataKeyNames="Id">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkRow" OnCheckedChanged="chkRow_CheckedChanged" AutoPostBack="true" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Document" ItemStyle-Width="10%" HeaderText="Documento" />
<asp:BoundField DataField="Entidad" ItemStyle-Width="55%" HeaderText="Entidad" />
</Columns>
For Each row As GridViewRow In gvEncomendasPendentes.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim chkRow As CheckBox = TryCast(row.Cells(0).FindControl("chkRow"), CheckBox)
If chkRow.Checked Then
'Bind with filter
End If
End If
Next
Does the table display the entire dataset at all times? If so, I'd check into client-side filtering (JavaScript). Not having the round trip to the server/database would make your page a lot more responsive.
But assuming that's not the case, and to actually answer the posted question, here's how I'd approach it in the VB.Net Code. Try changing the Change Event like this:
Protected Sub chkRow_CheckedChanged (sender as object, e As EventArgs)
Dim chk As CheckBox = DirectCast(sender, CheckBox)
dim grv As GridRowView = DirectCast(chk.NamingContainer, GridRowView)
dim hdn AS HiddenField = grv.FindControl("hdnFieldWithValue")
If chk.Checked then
AddValueToFilerList(hdn.Value)
Else
RemoveValueFromFilterList(hdn.Value)
End If
BindGridView()
End Sub
Your way does work, but that has a Log(N) time on processing, as it needs to look at every row in the grid. The above way will KNOW which checkbox was checked, and deal with it appropriately.
And this small change to the markup:
<asp:hiddenField runat='server' id='hdnFilterList' />
<asp:GridView ID="gridview" runat="server" AutoGenerateColumns="false" DataKeyNames="Id">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkRow" OnCheckedChanged="chkRow_CheckedChanged" AutoPostBack="true" runat="server" checked='<%# CheckValueInFilterList(Eval("Entidad")) %>' />
<asp:hiddenField id="hdnFieldWithValue" runat="server" value='<%# Eval("Entidad")' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Document" ItemStyle-Width="10%" HeaderText="Documento" />
<asp:BoundField DataField="Entidad" ItemStyle-Width="55%" HeaderText="Entidad" />
</Columns>
You'll also a function something like this:
Protected Function CheckValueInFilterList(input as string) as boolean
Return MyListOfFilterItems.Contains(input)
End Function
The purpose of that would be to see if the input is contained in your list of filters you're applying to your query and returning true/false depending on that.
Which is directly related to why you're not retaining a check in the checkboxes between postbacks. Since you're rebinding the grid, the existing form state is thrown away in favor of the values from the bind. Since your markup lacked a setter for the checkbox's checked state in the databind, it always resorted to false.
I also added a hidden field to the Markup which would contain the filter list as some type of serialized string (JSON, XML, etc). I'd read it from that field on the Page Load where IsPostBack is True, and always write the list to it in the PreRender event. The point is to just have that passed back and forth through the posted form state so that you can remember them between postbacks.
Maintaining that list of filters in a control outside of the gridview as described does add a bit of overhead in the data that is sent to/from the server on roundtrips. But I wouldn't expect that to a large amount, and would expect a preformance increase due to not having to iterate through the entire gridview item list on every postback.

OnCheckChanged not Firing when Unchecked

I've googled this topic as much as i could, ive found similar topics around and even on stackoverflow but none were able to resolve my issue. I have a nested gridview bound to a sqldatasource that populates a few fields as well as a checkbox field from a 'bits' field in the database. The checkboxes populate correctly from the database (checked vs. unchecked) but my 'OnCheckedChanged' event only fires when i check a checkbox but does NOT fire when it is unchecked, the page just goes through its post back. I have 'EnableViewState' set to true on the master page, local page, and on the control as well as auto post back. What i need to do is update the DB with the new value of the checkbox (checked vs unchecked) and reload. Please let me know if anyone has suggestions.
Protected Sub Gridview3_OnCheckedChanged(Sender As Object, e As EventArgs)
Dim checkbox As CheckBox = TryCast(Sender, CheckBox)
Dim gridview3 As GridView = checkbox.Parent.Parent.Parent.Parent
Dim row As GridViewRow = checkbox.Parent.Parent
sql_insert(String.Format("UPDATE [STOREIT2-PORTAL].dbo.AA5VOLUMES SET PROTECTED = '{0}' WHERE GUID = '{1}' AND AGENTID = '{2}'", checkbox.Checked, gridview3.DataKeys(row.RowIndex).Values("GUID").ToString, gridview3.DataKeys(row.RowIndex).Values("AgentID").ToString))
End Sub
<asp:GridView ID="Gridview3" EnableViewState="true" runat="server" AutoGenerateColumns="False" DataKeyNames="AgentID,GUID" OnRowDataBound="GridView3_OnRowDataBound" RowStyle-CssClass ="row" AlternatingRowStyle-CssClass="altrow" RowStyle-HorizontalAlign="Center" CssClass="gvmain"> <AlternatingRowStyle CssClass="altrow"></AlternatingRowStyle>
<columns>
<asp:BoundField DataField="AgentID" HeaderText="AgentID" SortExpression="AgentID" visible="false"/>
<asp:BoundField DataField="GUID" HeaderText="GUID" SortExpression="GUID" visible="false"/>
<asp:BoundField DataField="VolumeName" HeaderText="VolumeName" SortExpression="VolumeName" readonly="true"/>
<asp:BoundField DataField="Label" HeaderText="Label" SortExpression="Label" nulldisplaytext="<i>{No Label}</i>" readonly="true"/>
<asp:BoundField DataField="BaseCount" HeaderText="BaseCount" SortExpression="BaseCount" nulldisplaytext="<i>{No Base Images}</i>" readonly="true"/>
<asp:BoundField DataField="TimeStamp" HeaderText="TimeStamp" SortExpression="TimeStamp" nulldisplaytext="<i>{Volume has no recent snapshots}</i>" readonly="true"/>
<asp:TemplateField headertext="Protected">
<ItemTemplate>
<asp:CheckBox ID="Protected" EnableViewState="true" runat="server" autopostback="true" checked='<%# Eval("Protected")%>' OnCheckedChanged="Gridview3_OnCheckedChanged"/>
</ItemTemplate>
</asp:TemplateField>
</columns>
</asp:GridView>
I'm noticing your code does not have the 'Handles Clause' Maybe this is causing the problem you mention. . .
Handles CheckBox1.CheckedChanged

Lost Focus Events for a Control Within GridView

I have multiple textboxes and dropdown lists within my GridView. For one particular textbox I need trigger a server event which gets data from the database and fills it in other columns of the Grid. Is there a simple way to do it or a slightly complicated way as detailed here
I have no problems implementing the above method or thinking of a work around but then thought that there is Cell Lost Focus in a grid control surprises me a little. Am I missing something ? Any help on this would appreciated.
You can set AutoPostBack to true and handle it's TextChanged event.
<asp:GridView ID="GridView1" runat="server" EmptyDataText="It's Empty.">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:TextBox ID="txtName"
runat="server"
Text='<%#Eval("Name") %>'
AutoPostBack="true"
OnTextChanged="NameChanged" >
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</GridView>
in codebehind:
protected void NameChanged(Object sender, EventArgs e)
{
var txtName = (TextBox) sender;
var row = (GridViewRow) txtName.NamingContainer;
// you could find other controls in this GridViewRow via
// row.FindControl("ControlID") in case of a TemplateField or
// row.Cells[0].Text (0 = index of column) in case of a BoundField
}

Calling Data From GridView

I have a GridView with a bunch of DynamicFields like so;
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridDataSource">
<Columns>
<asp:DynamicField HeaderText="Date Submitted" DataField="DATE_CREATED" />
<asp:DynamicField HeaderText="Assigned To" DataField="ASSIGNED_TO" />
<asp:DynamicField HeaderText="Active Account" DataField="Active_Account" />
<asp:DynamicField HeaderText="Client ID" DataField="CLIENT_ID" />
<asp:DynamicField HeaderText="Client Type" DataField="CLIENT_Type" />
</Columns>
</asp:GridView>
<asp:EntityDataSource ID="GridDataSource" OnSelected="TotalRows" runat="server"
EnableDelete="true">
<WhereParameters>
<asp:DynamicControlParameter ControlID="FilterRepeater" />
</WhereParameters>
</asp:EntityDataSource>
Now it displays fine, the right data comes to screen but when I try to access that data using a row number I'm always finding blank cells. For example I tried the following to check every cell but to no avail;
Dim x As Integer = 0
Dim y As Integer = 0
While x < GridView1.Rows.Count
While y < GridView1.Rows(x).Cells.Count
If Not (GridView1.Rows(x).Cells(y).Text = "") Then
MsgBox(String.Format("{0},{1},{2}", x.ToString, y.ToString,
GridView1.Rows(x).Cells(y).Text))
End If
y = y + 1
End While
x = x + 1
y = 0
End While
No message box displayed so all the cells are empty strings. But I can clearly see they're populated on screen! What am I doing wrong?
UPDATE
After Pilgerstorfer Franz suggestion that I look for Textbox elements I used the following code which basically looks at all the cells in the table and try's to pull data out of them and if it's not blank then display a msgbox (also informs me of any new controls I haven't accounted for);
If GridView1.Rows(0).RowType = DataControlRowType.DataRow Then
For r = 0 To GridView1.Rows.Count - 1
For c = 0 To (GridView1.Rows(r).Cells.Count - 1)
Dim cell = GridView1.Rows(r).Cells(c)
For b = 0 To cell.Controls.Count - 1
If (cell.Controls(b).GetType() Is GetType(TextBox)) Then
Dim td = CType(cell.Controls(b), TextBox)
Text = td.Text.Trim
ElseIf (cell.Controls(b).GetType() Is GetType(LiteralControl)) Then
Dim td = CType(cell.Controls(b), LiteralControl)
Text = td.Text.Trim
ElseIf (cell.Controls(b).GetType() Is GetType(DynamicControl)) Then
Dim td = CType(cell.Controls(b), DynamicControl)
Text = td.Table.Columns.Item(c).DisplayName()
Else
MsgBox(String.Format("New Control of type: {0}", cell.Controls(b).GetType().FullName))
End If
If Not Text = "" Then
MsgBox(String.Format("{0},{1},{2}", c.ToString, b.ToString, Text))
End If
Next
Next
Next
End If
Unfortunately most cells just contained DynamicControl and since I was putting the DisplayName into Text I was just getting the column header every time. So how do I get the text value property out of a DynamicControl?
Additional Info
I'm further confused by this problem because since this is a project that I'm updating there is initial code two lines of which are;
Dim UserID = Convert.ToInt32(GridView1.DataKeys(e.RowIndex).Value)
Dim clientType As String = GridView1.DataKeys(e.RowIndex).Item(1).ToString
These successfully bring back UserID and ClientType. Now I don't really understand DataKeys but I tried using;
Dim clientType As String = GridView1.DataKeys(e.RowIndex).Item(Num).ToString
where Num increases by one every time expecting it to bring back the rest of the row data, but I simply got an index was out of range error.
ANOTHER UPDATE!!
Here is another bit of the ASPX page but I'n not entirely certain what it does. Pilgerstorfer Franz created some code to look for the textboxes created by the dynamicControl. Now I'm wondering if this code here causes other types of controls to be used rather than Textboxes. Thoughts?
<asp:FilterRepeater ID="FilterRepeater" runat="server" Visible="false">
<ItemTemplate>
<h2><asp:Label ID="lblDisplay" runat="server" Text='<%#
Eval("DisplayName") %>' AssociatedControlID="DynamicFilter$DropDownList1" /></h2>
<asp:DynamicFilter runat="server" ID="DynamicFilter"
OnSelectedIndexChanged="OnFilterSelectedIndexChanged" />
</ItemTemplate>
<FooterTemplate><br /><br /></FooterTemplate>
</asp:FilterRepeater>
According to my assumptions (see comments) I did a small demo...
<asp:DynamicDataManager ID="DynamicDataManager1" runat="server">
<DataControls>
<asp:DataControlReference ControlID="GridView1" />
</DataControls>
</asp:DynamicDataManager>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ContactID" DataSourceID="EntityDataSource1" AllowPaging="true"
OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:DynamicField DataField="ContactID" ReadOnly="true" HeaderText="ContactID" />
<asp:DynamicField DataField="Title" HeaderText="Title" />
<asp:DynamicField DataField="FirstName" HeaderText="FirstName" />
<asp:DynamicField DataField="LastName" HeaderText="LastName" />
<asp:CommandField ShowEditButton="True" />
</Columns>
</asp:GridView>
<asp:EntityDataSource ID="EntityDataSource1" runat="server" ConnectionString="name=dbTestIT34_EFEntities"
DefaultContainerName="dbTestIT34_EFEntities" EnableFlattening="False" EnableUpdate="True"
EntitySetName="Contacts" EntityTypeFilter="Contact">
</asp:EntityDataSource>
And according to my data storage I did handle the rowUpdating event. Unfortunatelly accessing any control within a dynamic control is not easy. So I did a very quick and dirty hack...
protected void Page_Init(object sender, EventArgs e)
{
GridView1.EnableDynamicData(typeof(Contact));
EntityDataSource1.ContextType = typeof(dbTestIT34_EFEntities);
}
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
int row = 0;
int firstNameColumn = 2;
while (row < GridView1.Rows.Count)
{
// sorry, a little bit confusing ...
// as dynamic control generates other controls dynamically,
// this was the very first thing that worked for me!
TextBox t = GridView1.Rows[row].Cells[firstNameColumn].Controls[0].Controls[0].Controls[0] as TextBox;
if (t != null)
Debug.WriteLine(t.Text);
row++;
}
}
Hope that helps!
Iterating through the controls never worked for me so in the end I gave up and just queried the DB again... Eh it works.

problem in gridview control of user control

My problem is I am setting the datasource from parent page.But if I set disable to certain columns of gridview the event of the controls inside those disabled column template gets fired. Like I have a checkbox in one column, if disable that column from parent page while data binding the check_checked event is being fired.
here my code- user control aspx
<asp:TemplateField HeaderText="Exclude Null" ItemStyle-Width="50px">
<HeaderTemplate>
Exclude Null
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkExNull" OnCheckedChanged="chkExNull_OnCheckedChanged"
AutoPostBack="true" />
</ItemTemplate>
<ItemStyle HorizontalAlign="left" VerticalAlign="Top" />
<HeaderStyle HorizontalAlign="left" VerticalAlign="Top" />
</asp:TemplateField>
.cs file of parent
GridView gvCondition = (GridView)ucCondition.FindControl("gvCondition");
gvCondition.DataSource = ConditionFieldCollection;
gvCondition.Columns[5].Visible = false;
gvCondition.Columns[6].Visible = false;
gvCondition.Columns[7].Visible = false;
gvCondition.Columns[8].Visible = false;
gvCondition.DataBind();
What should I do, and is there any other way through which I can hide some of the columns of grid view control of user control??
Before your DataBind(). write this:
gvCondition.DataBound += new EventHandler(gvwCondition_DataBound);
and write in that method, the code to hide the columns.
Hope that helps.

Resources