How to add if-else statement to change BoundFields of GridView - c#

I am trying to do something like the code below:
<%= if(ddlChoice.SelectedItem.Value ==1) { %>
<asp:BoundField DataField="FirstName" HeaderText="First Name">
<HeaderStyle HorizontalAlign="Left" /></asp:BoundField>
<asp:BoundField DataField="LastName" HeaderText="Last Name">
<HeaderStyle HorizontalAlign="Left" /></asp:BoundField>
<%= } else { %>>
<asp:BoundField DataField="Name" HeaderText="Name">
<HeaderStyle HorizontalAlign="Left" /></asp:BoundField>
<%= } %>
I have a GridView, now I want to add if-else condition to change available BoundFields according to selected item in DropDownList... Please Guide me !!!

In short: You cannot place your if statement between BoundFields as you are trying to do.
As an alternative solution, you could change the Visible property of each BoundField either from code behind or by setting a boolean value to that attribute in your .aspx file.
Another alternative solution is to have more than one GridView and change their visibility upon user selection.

Related

Hide cells in GridView based on another column

I have the following GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="InvoiceID" HeaderText="SysInvoiceID" ReadOnly="True" SortExpression="SysInvoiceID" />
<asp:BoundField DataField="BillMonth" HeaderText="BillMonth" SortExpression="BillMonth" />
<asp:BoundField DataField="InvoiceDate" HeaderText="InvoiceDate" ReadOnly="True" SortExpression="InvoiceDate" />
<asp:BoundField DataField="InvoiceNumber" HeaderText="InvoiceNumber" SortExpression="InvoiceNumber" />
<asp:BoundField DataField="Net" HeaderText="Net" SortExpression="Net" />
<asp:BoundField DataField="VAT" HeaderText="VAT" SortExpression="VAT" />
<asp:BoundField DataField="Gross" HeaderText="Gross" SortExpression="Gross" />
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</Columns>
</asp:GridView>
The very last column (ButtonField) is one I created myself just to include the text 'View' on each row, which when clicked, will bring up a PDF invoice.
I'm not sure if this is even possible, but I was wondering if it was possible to add some sort of validation for that column or something, so that if the 'InvoiceID' column is blank, the 'View' link on the corresponding row won't show up.
I felt close to doing this by going on split view in Visual Studio and then the 'Edit Columns' button on GridView tasks, but like I said I'm not sure if it's possible to do it this way and may have to resort to simply coding it.
Thanks for any help!
Use a <TemplateField> instead of a <ButtonField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" Text="View"
Visible='<%# Eval("IsEmpty(InvoiceID)") %>' CommandName="ViewInvoice" />
</ItemTemplate>
</asp:TemplateField>
And add a method to your page that is IsEmpty(string id) or whatever type your id is, and just check to see if it's empty first.
You can also add a CommandArgument attribute to the Button that will let you specify what the argument to it will be.
Use a placeholder...
<asp:Placeholder runat="server" ID="plView" Visible="<%# Convert.ToBoolean(InvoiceID == null) ? false : true %>">
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</asp:Placeholder>

Add sorting to a Nested Gridview ASP.net with C#

I have searched high and low for how to implement this on my page. I have a top level gridview which allows sorting and nested gridviews which are dynamically generated when the page compiles so 'x' number of nested gridviews which are inside dynamic html divs which can be toggled from invisible to visible at the users command. The problem I have is that I cannot figure out how to allow sorting on these nested gridviews without collapsing the divs/causing a postback.
Below shows how the master gridview (gvSalesDiv) and the nested gridview (gvTheDivisionCustomers) are generated in asp.net
<asp:GridView ID="gvSalesDiv" AllowSorting="true" onsorting="GridView1_Sorting" runat="server" GridLines="Both" OnRowDataBound="gvOrderLineDetail_RowDataBound" AutoGenerateColumns="False"
Width="100%" Height="210px" BackColor="WhiteSmoke" AlternatingRowStyle-BackColor="#DADDE2"
HeaderStyle-Font-Size="Medium" Visible="true">
<Columns>
<asp:TemplateField HeaderText="Toggle Detail">
<ItemTemplate>
<a href="javascript:switchViews('div<%# Eval("SalesDivision") %>');">
<img id="imgdiv<%# Eval("SalesDivision") %>" alt="toggle" border="0"
src="/salesconsole/toggle-off.png" />
</a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="SalesDivision" HeaderText="Sales Division">
<ItemStyle Font-Bold="True" ForeColor="CornflowerBlue" HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="LastDay" SortExpression="LastDay" DataFormatString="{0:C}" HeaderText="Last 24 Hours" >
</asp:BoundField>
<asp:BoundField DataField="LastWeek" SortExpression="LastWeek" DataFormatString="{0:C}" HeaderText="Last 7 Days" >
</asp:BoundField>
<asp:BoundField DataField="Last30Days" SortExpression="Last30Days" DataFormatString="{0:C}" HeaderText="Last 30 Days" >
</asp:BoundField>
<asp:BoundField DataField="Last3Months" SortExpression="Last3Months" DataFormatString="{0:C}" HeaderText="Last 3 Months" >
</asp:BoundField>
<asp:BoundField DataField="Last6Months" SortExpression="Last3Months" DataFormatString="{0:C}" HeaderText="Last 6 Months" >
</asp:BoundField>
<asp:BoundField DataField="LastYear" SortExpression="LastYear" DataFormatString="{0:C}" HeaderText="Last Year" >
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<tr>
<td colspan="100">
<div id="div<%# Eval("SalesDivision") %>" style="display:none;position:relative;left:25px;" >
<h3 title="<%# Eval("SalesDivision") %> Sales"><%# Eval("SalesDivision") %> Sales Breakdown</h3>
<asp:GridView ID="gvTheDivisionCustomers" AllowSorting="true" onsorting="GridView2_Sorting" BackColor="WhiteSmoke" AlternatingRowStyle-BackColor="#DADDE2"
Width="100%"
AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="Show More Detail">
<ItemTemplate>
<a href="sales-customers-detail.aspx?CustomerID=<%# Eval("CustomerID") %>&CustomerName=<%# Eval("CustomerName") %>" target="_blank" style="color:Blue; text-decoration:underline"> More Details
</a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CustomerID" HeaderText="ID"/>
<asp:BoundField DataField="CustomerName" HeaderText="Name" />
<asp:BoundField DataField="Last24Hours" HeaderText="Last 24 Hours" SortExpression="LastDay" DataFormatString="{0:C}" />
<asp:BoundField DataField="Last7Days" HeaderText="Last 7 Days" SortExpression="Last7Days" DataFormatString="{0:C}" />
<asp:BoundField DataField="Last30Days" HeaderText="Last 30 Days" SortExpression="Last30Days" DataFormatString="{0:C}" />
<asp:BoundField DataField="Last3Months" HeaderText="Last 3 Months" SortExpression="Last3Months" DataFormatString="{0:C}" />
<asp:BoundField DataField="Last6Months" HeaderText="Last 6 Months" SortExpression="Last6Months" DataFormatString="{0:C}" />
<asp:BoundField DataField="LastYear" SortExpression="LastYear" HeaderText="Last Year" DataFormatString="{0:C}" />
</Columns>
</asp:GridView>
</div>
</td></tr>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I populate the master gridview on Page_Load and the nested gridviews are created using the OnRowDataBound method. I have a sorting method for the master gridview which works fine as well. Below is the OnSorting method for the nested gridview, which is where I am stuck...I cannot access this object
protected void GridView2_Sorting(Object sender, GridViewSortEventArgs e)
{
// TO DO : Sort the nested gridview....All I can get at is the sort expressions or
cast the sender into a gridview but even then I wouldn't know the correct SQL query to bind with unless I knew which 'div' I was in...
}
So basically we can say, that you are looking for an ID or something wherewith you can create the query for the sorting method?
If that is correct we can find a solution.
Put a new label inside the first gridviews(gvSalesDiv) ItemTemplate like this one:
<asp:Label ID="lblID" runat="server" Text='<%# Bind("Id") %>'></asp:Label>
And in the codebehinde you can find it in this was:
Label lblID = (Label)((GridView)sender).NamingContainer.FindControl("lblID");
Hope it works!
If you are looking for how to get the parent div the gridview resides in, you can use this:
First, you need to cast the sender to a gridview, then create an html element and cast it to the gridview's parent. Like this:
Dim test As Button = CType(sender, Button)
Dim div As HtmlGenericControl
div = CType(test.Parent, HtmlGenericControl)
Dim t As String = test.ID
In this example, I'm casting the sender to a button but you can easily change this. IN this example, you will need to have the div run at the server, using " runat="server"". If you do not want to create it on the server side, you can change how you cast from a HTMLGenericControl to ContentPlaceHolder. Let me know if this helps or you need more information.

Difference between <Fields> and <Columns> in <asp:GridView>

Well it so happens that I am kind of a novice to asp.net and trying to create a Grid whose source is declared programmatically.
In the process, I came across 2 tags Fields and Columns. Can anyone please tell me how they are different?
EDIT: I went through some sample MSDN examples, and for all I can tell it seems to me they can be used interchangeably(though I have a feeling thats not true!).
Check this out:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="EmployeeID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
<asp:BoundField DataField="Title" HeaderText="Title"
SortExpression="Title" />
<asp:BoundField DataField="HireDate" HeaderText="HireDate"
SortExpression="HireDate" />
</Columns>
</asp:GridView>
And then there is:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName"
HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice"
DataFormatString="{0:c}"
HeaderText="Price"
HtmlEncode="False" SortExpression="UnitPrice" />
</Fields>
</asp:GridView>
Seem similar or is it just me??!
Thanks for helping.
Columns is just the surrounding tag for the fields which are
TemplateFields with any controls you want or
BoundFields which are created automatically
So Columns enclose the list of fields in the GridView.
<Columns>
<asp:Boundfield datafield="StudentID"
readonly="true"
headertext="Student ID"/>
<asp:TemplateField HeaderText="Student" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:label runat="server" Font-Bold="true" ID="LblStudent" Text='<%# Bind("Student") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Inner Grid">
<ItemTemplate>
<asp:GridView ID="Grid2" AutoGenerateColumns="false" runat="server" GridLines="None" Width="300">
<RowStyle CssClass="GridViewRowStyle" />
<AlternatingRowStyle CssClass="GridViewAlternatingRowStyle" />
<HeaderStyle CssClass="GridViewHeaderStyle" />
<SelectedRowStyle BackColor="Aqua" />
<Columns>
<asp:TemplateField HeaderText="Student" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:label runat="server" Font-Bold="true" ID="LblStudent" Text='<%# Bind("Student") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
As you can see, a TemplateField could also contain another nested GridView.
Am I blind or wat!
After I posted this question I went back to my drawingboard and as it turns out, there is no Fields tag in asp:GridView, right?!
Please do let me know if this is true people(and prove me silly!)
Putting aside this particular control for a moment, it might be helpful to look at this from a general computer science point of view.
In classic programming (ANY LANGUAGE), a FIELD would be the INTERSECTION of a row and a column -- a discrete piece of data. For example, if a table has 20 rows of data containing first and last names, if you went to the 19th row and looked in the "first name" column, you've got a FIELD. Perhaps it contains the discrete data "JOHN".
COLUMNS then would be collections of like data -- in this example, you have the two columns "first name" and "last name". Columns would have attributes such as a data type, maximum length, constraints (are nulls OK?, etc.) and so forth.
Some may quibble with my definitions and say that individual cells in a COLUMN would be called a FIELD. It's not uncommon to hear that. I would reply that for a table with a single column, it'd be especially true :-) But the takeaway point is this: COLUMNS are generally containers for smaller, more discrete items such as FIELDS. FIELDS typically refer to a single piece of data, such as you'd find at the intersection of a row and column in a database table.

User Control Properties?

Can I build a control that basically acts "like a MasterPage"?
What I mean to do is, say I have a grid like this in a number of pages:
<asp:UpdatePanel ID="AnnouncementsPanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:GridView ID="AnnoucementsGrid" runat="server" AutoGenerateColumns="false" DataKeyNames="Id" >
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Created" HeaderText="Date" />
<asp:BoundField DataField="Modified" HeaderText="Last Modified" />
<asp:ButtonField ButtonType="Button" Text="Process" CommandName="Process" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
I'd like to build a control that handles most of the codebehind, but I need to declare the columns for the grid declaratively in each case.
Is there a way to create a control like this?
<uc:CrudGrid ID="AnnouncementsCrud" runat="server">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Created" HeaderText="Date" />
<asp:BoundField DataField="Modified" HeaderText="Last Modified" />
<asp:ButtonField ButtonType="Button" Text="Process" CommandName="Process" />
</Columns>
</uc:CrudGrid>
or event better:
<uc:CrudGrid ID="AnnouncementsCrud" runat="server">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Created" HeaderText="Date" />
<asp:BoundField DataField="Modified" HeaderText="Last Modified" />
</Columns>
</uc:CrudGrid>
Maybe having to name the tag "Fields", but being able to drop the button, so it can be used in the UC's code-behind?
A lot of love to whoever has a positive answer on this <3
Found the exact solution I was looking for:
[DefaultValue((string)null)]
[Editor(typeof(System.Web.UI.Design.WebControls.DataControlFieldTypeEditor), typeof(UITypeEditor))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public DataControlFieldCollection Columns
{
get { return Grid.Columns; }
}
this way I can expose the Columns from the grid in my own user control and edit the fields from the markup, keeping general functionalities within my UC
Depends on how positive you want it to be :-) You can always build your own control to do this. That is one option.
Another option is to create a helper object that attaches to the grid, and keep each grid separate.
Third option is to create a user control with the common code, and programmably add columns to the grid through the user control.
HTH.

How do I make the gridview headers to links?

I want the headers of my gridview to be hyperlinks, without the "SortExpression"...
I searched the net, but I've been not very succesful.
Anyone has the solution?
For example: when clicking on the header of a simple gridview, the site navigates to a webpage. Is it possible?
Thanks in advance!
Have you tried Gridview Header template like...
<asp:GridView runat="server" ID="grd">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:HyperLink runat="server" NavigateUrl="YourURL"> </asp:HyperLink>
</HeaderTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I think a HeaderTemplate is needed here...
Ref.: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.templatefield.headertemplate.aspx
HTH.
Now I got this gridview, And I need the headers to be clickable, whereafter an event starts (something like OnClickHeader="header_ClickEvent"?) Ofcourse there is a SortExpression element, which enables to sort the grid, but I want to be able to start any event, like when clicking a button.
I could not find any solution within the asp:BoundField nor asp:TemplateField...
I thought a hyperlink could solve the problem, but that was a bit premature.
The Gridview:
<asp:GridView CssClass="gridview" ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="Student_key" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" PagerSettings-Visible="false" PageSize="14">
<HeaderStyle CssClass="headerstyle" />
<RowStyle CssClass="rowstyle"/>
<AlternatingRowStyle CssClass="altrowstyle" />
<Columns>
<asp:BoundField DataField="Studentnumber" HeaderText="Studentnummer" >
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:BoundField DataField="Prefix" HeaderText="Voorletters" >
<HeaderStyle CssClass="header75" />
</asp:BoundField>
<asp:BoundField DataField="prename" HeaderText="Voornaam" SortExpression="Voornaam">
<HeaderStyle CssClass="header75" />
</asp:BoundField>
<asp:BoundField DataField="nickname" HeaderText="Roepnaam" >
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:BoundField DataField="insertion" HeaderText="Tussenvoegsel" >
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:BoundField DataField="surname" HeaderText="Achternaam">
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:CommandField SelectText="show results" ShowSelectButton="True" >
<HeaderStyle CssClass="header100" />
</asp:CommandField>
</Columns>
<EmptyDataTemplate >There are no results shown, please try again.</EmptyDataTemplate>
</asp:GridView>
I used a method that might be a little unconventional but it works. In my case I wanted to use the standard BoundField controls in my gridview as opposed to using a template field with both a HeaderTemplate and ItemTemplate. I used a simple gridview based on a SQL datasource that looks like this.
<asp:GridView
ID="gvTopXByContest"
runat="server"
AutoGenerateColumns="False"
DataSourceID="dsTopXByContest"
AllowSorting="true"
OnSorting="gvTopXByContest_OnSorting" >
<Columns>
<asp:BoundField DataField="txtOnlineUserName" HeaderText="Fan Name & Rank" SortExpression="txtOnlineUserName" ItemStyle-Width="155px"></asp:BoundField>
<asp:BoundField DataField="fltTotalPoints" HeaderText="Points" SortExpression="fltTotalPoints" ItemStyle-Width="40px"></asp:BoundField>
<asp:BoundField DataField="curWon" HeaderText="Won" SortExpression="curWon" ItemStyle-Width="40px"></asp:BoundField>
</Columns>
</asp:GridView>
I then used code that fires on the OnSorting event of the gridview to do my redirects
Protected Sub gvTopXByContest_OnSorting(sender As Object, e As GridViewSortEventArgs)
If e.SortExpression <> DirectCast(sender, GridView).SortExpression Then
If e.SortExpression = "txtOnlineUserName" Then
Response.Redirect(URL to redirect to goes here)
ElseIf e.SortExpression = "fltTotalPoints" Then
Response.Redirect(URL to redirect to goes here)
Else
'I could have used another ElseIf here but since there are only 3 columns Else works
Response.Redirect(URL to redirect to goes here)
End If
End Sub

Categories

Resources