Gridview Header customizing issue - c#

If we add a customer header to the gridview, will it add extra row?
Currently I have a gridview with four columns and, when I add a custom header gridview coming with a five rows.
My code looks like this...
<asp:TemplateField HeaderText="" ItemStyle-Width="4%" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
<HeaderTemplate>
<asp:DropDownList ID="Select" runat="server">
<asp:ListItem>Country</asp:ListItem>
<asp:ListItem>Region</asp:ListItem>
<asp:ListItem>Title</asp:ListItem>
</asp:DropDownList>
</HeaderTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="" ItemStyle-Width="4%" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:HiddenField ID="Id" Value='<%#Eval("id")%>' runat="server" />
<asp:Literal ID="ltrImage" runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
and three other TemplateFields...
Is there any problem of adding header this way? Any other way to add customer header without having this issue?
My desired output should look like this
Search Result Search By (Dropdownlist)
Data column1 Data column2 Data column3 Data column4
The one I am getting now is
Sort By (Dropdownlist)
Data column1 Data column2 Data column3 Data column4
Could anyone help if have an idea?
Thanks in advance

You just added another column with custom header to your gridview. If you want to customize a header of the first column, just customize the header of your first template field:
<asp:TemplateField HeaderText="" ItemStyle-Width="4%" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
<HeaderTemplate>
<asp:DropDownList ID="Select" runat="server">
<asp:ListItem>Country</asp:ListItem>
<asp:ListItem>Region</asp:ListItem>
<asp:ListItem>Title</asp:ListItem>
</asp:DropDownList>
</HeaderTemplate>
<ItemTemplate>
<asp:HiddenField ID="Id" Value='<%#Eval("id")%>' runat="server" />
<asp:Literal ID="ltrImage" runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
If this dropdownlist is too big or if you want add some additional text in the header, you can always create HeaderTemplate for other TemplateFields of merge some of the column's headers in code behind (example for "merging" two first headers, Id of the gridView is gridView1):
protected void gridView1_PreRender(object sender, EventArgs e)
{
int indexOfColumnToSpan = 0;
int indexOfColumnToRemoveHeader = 1;
gridView1.HeaderRow.Cells[indexOfColumnToSpan].ColumnSpan = 2;
gridView1.HeaderRow.Cells.RemoveAt(indexOfColumnToRemoveHeader);
}

well, you have not actually added a header row, but a header column .. which is basically just another column with more controls ..
why dont you place your DropDownList before your GridView, and then you can write some code behind handling the DropDownList_SelectedIndexChanged event to sort the Data ?

I have implemented this without using the filters within the GridView. Then you can handle the events separately, and populate the GridView accordingly.
What you are actually adding is a column, instead of a row. That's why you are getting that result.
Hope this helps!

Related

Create Dynamic ItemTemplate based on GUID column names

I have a process that pivots data to create columns based on the UniqueIdentifier key value. The resulting data table has column names such as:
> PartNum
> [DB1A6498-7CC6-4EA0-846A-9B6EAB771777]
The portion of ASP is:
<asp:TemplateField HeaderText="Part No.">
<ItemTemplate>
<asp:Label ID="lblPartNum" runat="server" Text='<%#Eval("PartNum") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Run Out">
<ItemTemplate>
<asp:Label ID="lblRunOut" runat="server" Text='<%#Eval("DB1A6498-7CC6-4EA0-846A-9B6EAB771777") %>' />
</ItemTemplate>
</asp:TemplateField>
The Part Number displays just fine, however field based on the uniqueID results in a message:
DB1A6498-7CC6-4EA0-846A-9B6EAB771777/ is neither a DataColumn nor a DataRelation for table .
I read through the data table columns to create the grid columns, which display fine, however when attemtping to dynamically create the ItemTemplate, the error occurs. Putting the brackets "[]" around the uniqueID in the label did not work either.
Any suggestions are greatly appreciated. Thanks
Kevin...your response led me down the path of the brackets. Based on that, I found information about the DataBinder with the final result being that the Text property of the asp:label reads:
Text='<%# DataBinder.GetPropertyValue(Container.DataItem,"[DB1A6498-7CC6-4EA0-846A-9B6EAB771777]") %>'
This is displaying data from the uniqueID fields with no errors.

CommandName = Insert in EditTemplate of ASP.NET ListView throws "Insert can only be called on an insert item"

I am supporting a web application. In that, there are two tables - TaxCode and TaxRate. TaxCode has 1 to many relationship with TaxRate.
The UI has a ListView with LayoutTemplate, ItemTemplate and EditTemplate to show TaxCode. When the users selects a tax code in EditTemplate it shows a CutomGridView that allows the user to create or edit tax rates for that particular tax code. This CustomGridView has 3 rows each has 4 template fields as shown below.
<asp:TemplateField HeaderStyle-CssClass="highlightTitlebar" HeaderStyle-Width="5%" HeaderStyle-Height="30px">
<HeaderTemplate>
<custom:CustomImageButton ID="imgAdd" runat="server" ImageUrl="image/add_round.gif" OnClick="imgAddTaxRateDetail_Click" CausesValidation="False"/>
</HeaderTemplate>
<ItemTemplate>
<custom:CustomImageButton ID="imgEdit" runat="server" ImageUrl="image/edit.gif" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="imgUpdate" runat="server" ImageUrl="image/update.gif" CommandName="Update" />
<asp:HiddenField runat="server" ID="hfId" Value='<%# Bind("Id") %>' />
</EditItemTemplate>
<FooterTemplate>
<asp:ImageButton ID="imgInsert" runat="server" ImageUrl="image/insert.gif" CommandName="Insert" OnClick="imgInsert_Click" />
</FooterTemplate>
Each row in the CustomGridView is a template field. In, below image EffectiveOn section is CustomGridView,
When I try to save TaxRate with proper EffectiveOn and Rate, it throws "Insert can only be called on an insert item. Ensure only the InsertTemplate has a button with CommandName=Insert." error as the ListView doesn't have InsertTemplate. But the record gets inserted into the DB.
Please let me know if there is any way to resolve this issue?
The error is self explanatory.
Take a look at this: https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.insertitemtemplate(v=vs.110).aspx
So you can do either of these things.
Create an InsertItemplate and insert using the ItemInserted event of the listview
Change the CommandName to CommandName="InsertData" and catch that event on the ItemCommand

Get the index of a row in a table from code behind

I have a table with two columns and multiple rows, the first column has names and the second one has buttons, how can I get the name next to the button when I click any button.
The names will be taken from a database and the buttons will be generated from code behind depending on the number of names I have in my database.
Let's say that I have this:
<asp:table runat="server" id="table1">
<tr><td>Name1</td><td><asp:Button runat="server" Text="Save"/></td></tr>
<tr><td>Name2</td><td><asp:Button runat="server" Text="Save"/></td></tr>
<tr><td>Name3</td><td><asp:Button runat="server" Text="Save"/></td></tr>
</asp:table>
How can I know which name is next to the button, when I click any of them, I want to get the name so that I can save it in a database.
use for your designer code something similar to this:
<asp:GridView ID="GridView" runat="server" OnRowCommand="gvUsers_RowCommand" AutoGenerateColumns="True">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="detail_LB" runat="server" Text="Detail" CommandName="Detail_LB" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Notice the OnRowCommand and for the LinkButtons the CommandName and CommandArgument. The argument contains the row number, where you clicked the button.
In your code behind:
protected async void gvUsers_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Detail_LB")
{
//index contains the row number
int index = Convert.ToInt32(e.CommandArgument);
//get text in the cell next to the button
string text = gvUsers.Rows[index].Cells[0].Text;
}
}
If hope this helps you to understand how to work with tables.

Merge column header in gridview

I've been try to merge the header column from 2 into 1, but the example and i already tried it with something like this
GridView.Controls[0].Controls.AddAt(0, oGridViewRow); the question and the example that floating around was just adding 1 column, and add it in the top of the old column, not merging it. So i want to actually merging 1 column and the rest of the column is still the same. Here is the picture of gridview column that i want to merge :
I want to Merge the "Action" column header from 2 into 1. So below the action column, there will be an edit and delete.
Oh i almost forgot, Here is the gridview code that handle the action column :
<asp:CommandField ShowEditButton="true" HeaderText="Action"/>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="linkDelete" runat="server"
CommandArgument = '<%# Eval("XXX")%>'
OnClientClick = "return confirm('Do you want to delete?')"
Text = "Delete" OnClick = "DeleteDetail"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Although I am strictly against hard-coding, this is what I have, you can write this in 'RowDataBound' event of gridview:-
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[3].ColumnSpan = 2;
e.Row.Cells[4].Visible = false;
e.Row.Cells[3].Text = "Action";
}
Here, You need the change the cell index according to your gridview design.
You can use Templates to customize how your column header and data look like
The below is a very simplified example that should show the desired result
But you will need to work on hadnling Edit and Delete actions your own way
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<div> Action </div>
</HeaderTemplate>
<ItemTemplate>
Edit | Delete
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
As you see, my idea is not merging the headers of both columns. Rather, I put the data of of both columns in a single column under single header. I think it achieves the same result.

How to pass codebehind value to HeaderTemplate label control of Gridview UI

In ASP.NET usign C#, .NET3.5 F/W
Hi,
I've a Gridview with template columns containing textbox and Label controls.
By code through some queries and stored procedures i got some data to a datatable. Now i want to pass this datatable column field or names to the Gridview Label controls.
How can i set the datatable column header names to gridview label control of Header Template?
It's called Binding here is link
<asp:TemplateColumn>
<ItemTemplate HeaderText="PersonId">
<asp:Label id=Label1 runat="server"
Text='<%# Eval("NameOfColumnt") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
Try this
<asp:TemplateColumn >
<ItemTemplate>
<asp:Label id=Label1 runat="server"
Text='<%# DataBinder.Eval(Container,EmployeeName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
For this to work you will have to give your grid view a data source:
yourGridView.DataSource = yourDataTable;
yourGridView.DataBind();
After you do this, you just have to link each control in template columns to column in datatable, for example:
<HeaderTemplate>SomeText</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="a" Text='<%# Eval("nameOfTheColumn") %>' runat="server"></asp:Label>
</ItemTemplate>
EDIT:
Regarding your other question, I suggest you to add bound fields to your grid view dynamically rather then right away in the aspx. Something like this:
foreach (DataColumn column in dt.Columns)
{
BoundField nameColumn = new BoundField();
nameColumn.DataField = column.ColumnName.ToString();
nameColumn.SortExpression = column.ColumnName.ToString();
nameColumn.HeaderText = column.ColumnName.ToString();
gridView.Columns.Add(nameColumn);
}
This way you don't have to know exactly how many columns you have, and have the ability to name them as they are in the data table.

Categories

Resources