I am using a GridView that has many rows with the same values, so I grouped these rows using GridViewHelper class. Now I want to put a separate line between each grouping values. How to do that?
The following snapshot shows you the current situation:
I wasn't sure if you wanted to style them when rendered or when you click the row. So here is both. You can decide what styles you want. :-)
Set the appropriate attributes in your ASP.NET GridView control for controlling CSS:
<asp:GridView ID="gridviewid"
runat="server"
CssClass="gridview"
AutoGenerateSelectButton="True"
GridLines="None"
AllowPaging="true"
PageSize="10">
<HeaderStyle CssClass="gridViewHeader" />
<RowStyle CssClass="gridViewRow" />
<AlternatingRowStyle CssClass="gridViewAltRow" />
<SelectedRowStyle CssClass="gridViewSelectedRow" />
<PagerStyle CssClass="gridViewPager" />
</asp:GridView>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.CssClass = "cssClass";
}
}
You can try something like...
protected void Page_Load(object sender, EventArgs e)
{
GridViewHelper helper = new GridViewHelper(this.GridView1);
helper.RegisterGroup("yourGroupName", true, true);
helper.GroupHeader += new GroupEvent(helper_GroupHeader);
}
private void helper_GroupHeader(string groupName, object[] values, GridViewRow row)
{
if (groupName == "yourGroupName" )
{
row.Cells[0].Text = "<br />" + row.Cells[0].Text;
}
}
You should also be able to insert a new one before row instead of just adding a break line to the cell if that's what you want.
Related
Simple problem.
I have an ASP.net GridView (VS2005) and it has page numbers, but when there is less than the maximum rows per page (< 10), the Pager row disappears. This makes my gridview look ugly, like as if there's a missing row at the bottom.
I can force display the Pager row, but I need to hide the page number 1, because it's obvious we're on PAGE ONE !
<asp:GridView ID="gvFTUNSENT" runat="server"
AutoGenerateColumns="False" CellPadding="4" ForeColor="Black" AllowSorting="True" CssClass="gvCSS" Width="100%"
DataKeyNames="StudentID,StudentUnitID" DataSourceID="sdsFTUNSENT"
GridLines="Vertical" AllowPaging="True" PageSize="10" BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px"
OnPreRender="GridView_PreRender"
OnLoad="GridView_Load"
OnRowDataBound="GridView_RowDataBound" >
<RowStyle Wrap="True" Height="48px" />
<Columns>
...blahblah
</Columns>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<PagerStyle CssClass="cssPager" BackColor="#6B696B" ForeColor="White" HorizontalAlign="Left" Height="100%" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<EmptyDataTemplate>
<asp:Label ID="lblNDF1" runat="server" Text="NO DATA FOUND" Font-Size="X-Large" Width="500px" style="text-align:center" />
</EmptyDataTemplate>
<EmptyDataRowStyle HorizontalAlign="Center" />
</asp:GridView>
Here I force show the Pager row...
protected void GridView_PreRender(object sender, EventArgs e)
{
GridView gv = (GridView)sender;
//keep showing pager line even if there is only one row of data
GridViewRow gvr = (GridViewRow)gv.BottomPagerRow;
if (gvr != null)
gvr.Visible = true;
}
But I don't want to see Page 1 in there, so I tried this ...
if (e.Row.RowType == DataControlRowType.Pager)
{
//keep showing pager line even if there is only one row of data
GridViewRow gvr = (GridViewRow)e.Row;
if (gvr != null)
{
gvr.Visible = true;
//...but hide page number if there is only one page
if (gv.PageCount == 1)
{
gv.ShowFooter = true;
gv.PagerSettings.Visible = false;
}
}
}
But it actually hides the entire Pager row! No! I want to hide only the page numbers.
The ShowFooter, is so it looks like the gridview is a box, closed off. But it's still ugly. I'd rather not use it if I can just keep the Pager row showing and being able to hide anything in it. ie.. keep background color intact.
Any other ideas? Thanks
Try something like
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager && GridView1.PageCount==1 )
{ e.Row.Style.Add("color", "white"); }
}
Or, if you don't want to deal with colors you can try this (but I think it's less robust)
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager && GridView1.PageCount==1 )
{
var a = e.Row.Controls;
if (a.Count>0 && a[0] is TableCell)
{
var b = a[0].Controls[0].Controls[0] as TableRow;
if (b != null)
{
//This is actually your page 1 text
b.Cells[0].Text = "";
}
}
}
}
try
e.Row.Controls.Clear();
insted
e.Row.Style.Add("color", "white");
its work better..
We have a webform with a radgrid and a button. The radgrid has two columns and a checkbox column.
On Page_load, the data will be displayed and the user will be able to select (via the checkbox) which rows will go through with the update of the EmpId; if the row is selected, NewEmpId will replace OldEmpId. The Update button is clicked and the changes are made.
The problem I'm having is that I prefer to use the datakeynames to retrieve the data from each row. But I'm having trouble implementing it without using GridCheckBoxColumn, which I don't want to use because the radgrid needs to be in Edit mode for the checkbox to be selected, and that brings other issues.
<telerik:RadGrid ID="RadGridEmp" runat="server" AutoGenerateColumns="False" Width="100%" AllowPaging="True" PageSize="22">
<ClientSettings>
<Selecting AllowRowSelect="True" />
</ClientSettings>
<mastertableview commanditemdisplay="TopAndBottom" datakeynames="OldEmpId, NewEmpId, EmpName">
<commanditemsettings showaddnewrecordbutton="false" />
<Columns>
<telerik:GridBoundColumn DataField="OldEmpId" HeaderText="OldEmpId">
<HeaderStyle Width="110px"></HeaderStyle>
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="NewEmpId" HeaderText="NewEmpId">
<HeaderStyle Width="110px"></HeaderStyle>
</telerik:GridBoundColumn>
<ItemTemplate>
<asp:CheckBox ID="ChkChange" runat="server" />
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</mastertableview>
</telerik:RadGrid>
The following code is just the code I prefer to use with this issue. It uses datakeynames. But it doesn't build:
protected void RadButtonUpdateSectors_Click(object sender, EventArgs e)
{
foreach (GridItem item in RadGridEmp.MasterTableView.Items)
{
GridDataItem dataitem = (GridDataItem)item;
TableCell cell = dataitem["GridCheckBoxColumn"];
CheckBox checkBox = (CheckBox)cell.Controls[0];
if (checkBox.Checked)
{
oldEmpId = dataitem.GetDataKeyValue("OldEmpId").ToString();
newEmpId = dataitem.GetDataKeyValue("NewEmpId").ToString();
UpdateEmpId(oldEmpId, newEmpId, connString);
}
}
}
Please try with the below code snippet.
datakeynames="OldEmpId,NewEmpId,EmpName"
...............
...............
protected void RadButtonUpdateSectors_Click(object sender, EventArgs e)
{
foreach (GridDataItem item in RadGridEmp.MasterTableView.Items)
{
CheckBox ChkChange = item.FindControl("ChkChange") as CheckBox;
if (ChkChange.Checked)
{
string oldEmpId = item.GetDataKeyValue("OldEmpId").ToString();
string newEmpId = item.GetDataKeyValue("NewEmpId").ToString();
UpdateEmpId(oldEmpId, newEmpId, connString);
}
}
}
Let me know if any concern.
Note:- Remove extra space from datakeynames.
I am trying to find the last row of my grid, and programmatically add a drop down list to the grid. My code compiles with no issues, but my RowDataBound is never hit when stepping through the code causing the list to never be added. What have I improperly coded?
EDIT
The page loads and you select an option from the drop down list. RefreshdatagridTest is called at that point.
End Of Edit
ASP Code
<div class="CenterGrid">
<asp:DataGrid runat="server" ID="datagridTest" AutoGenerateColumns="false"
Width="500px" CssClass="DataGrids" HorizontalAlign="Center" GridLines="Both"
ShowFooter="true" OnSelectedIndexChanged="datagridTest_SelectedIndexChanged"
OnItemCommand="datagridTest_ItemCommand" RowDataBound="datagridTest_RowDataBound" Visible="true">
<ItemStyle CssClass="row" />
<FooterStyle CssClass="DataGridFooters" />
<HeaderStyle CssClass="DataGridHeaders" />
<Columns>
<asp:BoundColumn DataField="Firefly" HeaderText="Name"></asp:BoundColumn>
<asp:ButtonColumn CommandName="Delete" HeaderText="Delete From List" Text="[Remove]"></asp:ButtonColumn>
</Columns>
</asp:DataGrid>
</div>
C# Code
protected void datagridTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex == datagridTest.Items.Count - 1)
{
DropDownList ddl = new DropDownList();
e.Row.Cells[0].Controls.Add(ddl);
}
}
protected void datagridTest_ItemCommand(object source, DataGridCommandEventArgs e)
{
LinkButton lnkbtn = ((LinkButton)e.CommandSource);
if (e.CommandName == "Delete")
{
DataGridItem deletecontrol = (DataGridItem)lnkbtn.NamingContainer;
string bomb = deletecontrol.Cells[0].Text;
RemoveFireflyFromList(bomb);
RefreshdatagridTest();
}
}
How the grid gets data bound
protected void listselect_SelectedIndexChanged(object sender, EventArgs e)
{
RefreshdatagridTest();
}
private void RefreshdatagridTest()
{
dataSet = Run sql procedure to get results;
this.datagridTest.DataSource = dataSet;
this.datagridTest.DataBind();
}
its bit differente since in my exemple i generate new row at runtime but basicaly its how it work;
in my case had to add some size param or control was hidden.
so i just get to set control row's and add the row to the grid.
Mycontrol m = new Mycontrol();
RowDefinition rowDef1 = new RowDefinition();
rowDef1.MaxHeight = m.ExpandedSise;
rowDef1.MinHeight = m.Height;
rowDef1.Height = new GridLength(m.RowDefColapsedSize);
int rownumber = grid2.RowDefinitions.Count;
grid2.RowDefinitions.Insert(rownumber, rowDef1);
Grid.SetRow(m, rownumber);
m.counter.Content = Grid.GetRow(m).ToString();
grid2.Children.Add(m);
I've spent all afternoon trying to do this using CODE BEHIND without success so I am asking for some C# code.
Basically, I have a GV and a DV in a master/detail relationship. GV displays ID and Name. If I click Select on a GV row, I want to see its ID, Name and Address in DV. I know how get this to work declaratively in an aspx file. But in C# code behind, I don't know how to proceed at this function:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("Select"))
{
// PLEASE GIVE ME THE CODE HERE TO BIND THE DETAILSVIEW. THANKS!
// I am using a sqldatasource if it makes any difference
}
}
Here's a general solution showing you how to achieve this, please note that this solution isn't extremely error-safe but I suppose you'll get the jist of it. Please comment if there's anything unclear.
Code-behind:
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow selected = gv.Rows[Convert.ToInt32(e.CommandArgument)];
List<ThatClass> cList = new List<ThatClass>();
cList.Add(new ThatClass(selected.Cells[0].Text, selected.Cells[1].Text));
dv.DataSource = cList;
dv.DataBind();
}
}
Markup:
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false" OnRowCommand="gv_RowCommand">
<Columns>
<asp:BoundField DataField="A" HeaderText="A"/>
<asp:BoundField DataField="B" HeaderText="B" />
<asp:CommandField ShowSelectButton="true" />
</Columns>
</asp:GridView>
<asp:DetailsView runat="server" ID="dv">
</asp:DetailsView>
FYI: I bound the GV using a List:
protected void Page_Load(object sender, EventArgs e)
{
List<ThatClass> cList = new List<ThatClass>();
cList.Add(new ThatClass("123", "abc"));
cList.Add(new ThatClass("456", "def"));
gv.DataSource = cList;
gv.DataBind();
}
Please consider the values in comments which I got in debug mode:
protected void FilesGrid_SelectedIndexChanged(object sender, EventArgs e)
{
int selected = FilesGrid.SelectedIndex; // selected = 2
FilesGrid.DataBind(); //added after feedback in comments. it makes no change
int count = FilesGrid.Rows.Count; // count = 0
GridViewRow row = FilesGrid.Rows[selected]; // row = null
GridViewRow row0 = FilesGrid.Rows[0]; // row = null
}
I came to this code while investigating why SelectedValue gives null in this event handler (the DataKeyNames parameter was set for sure).
Can anybody explain how it is possible?
Thank you in advance.
PS.
Here is my aspx code:
<asp:GridView ID="FilesGrid" runat="server" AutoGenerateColumns="False"
AutoGenerateSelectButton="True"
onselectedindexchanged="FilesGrid_SelectedIndexChanged"
style="margin-top: 0px" >
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Length" DataFormatString="{0:N0}"
HeaderText="Size in Bytes" HtmlEncode="False" />
</Columns>
</asp:GridView>
Here is how I bind data:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string [] dd = {"FullName"};
FilesGrid.DataKeyNames = dd;
string appPath = Request.PhysicalApplicationPath;
DirectoryInfo dirInfo = new DirectoryInfo(appPath);
FileInfo[] files = dirInfo.GetFiles();
FilesGrid.DataSource = files;
FilesGrid.DataBind(); }
}
Y copy pasted your code, delete this line FilesGrid.DataBind() in the FilesGrid_SelectedIndexChanged, i see that are 2 methods that you are not posting, that aren't in the code that you posted the onselectedindexchanging, onrowdeleting events, comment them from the aspx and see if it works, or se if that events are not doing something tricking, that are deleting the rows in your GridView.
Tell me if it works
I did this
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string[] dd = { "FullName" };
FilesGrid.DataKeyNames = dd;
string appPath = Request.PhysicalApplicationPath;
DirectoryInfo dirInfo = new DirectoryInfo(appPath);
FileInfo[] files = dirInfo.GetFiles();
FilesGrid.DataSource = files;
FilesGrid.DataBind();
}
}
protected void FilesGrid_SelectedIndexChanged(object sender, EventArgs e)
{
int selected = FilesGrid.SelectedIndex; // selected = 2
//FilesGrid.DataBind(); //added after feedback in comments. it makes no change
int count = FilesGrid.Rows.Count; // count = 0
GridViewRow row = FilesGrid.Rows[selected]; // row = null
GridViewRow row0 = FilesGrid.Rows[0]; // row = null
}
protected void FilesGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
}
protected void FilesGrid_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
}
The aspx code.
<asp:ScriptManager ID="ScriptManager1" runat="server" EnableScriptGlobalization="true"
AsyncPostBackTimeout="0" EnableScriptLocalization="true">
</asp:ScriptManager>
<asp:UpdatePanel ID="upPanel" runat="server">
<ContentTemplate>
<asp:GridView ID="FilesGrid" runat="server" AutoGenerateColumns="False" AutoGenerateSelectButton="True"
OnRowDeleting="FilesGrid_RowDeleting" OnSelectedIndexChanged="FilesGrid_SelectedIndexChanged"
Style="margin-top: 0px" OnSelectedIndexChanging="FilesGrid_SelectedIndexChanging">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Length" DataFormatString="{0:N0}" HeaderText="Size in Bytes"
HtmlEncode="False" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
remove the FilesGrid.DataBind(); //added after feedback in comments. it makes no change
When I add that statement to my code I am getting the error. after removing that please try again. If not working please share the
protected void FilesGrid_SelectedIndexChanging(object sender, GridViewSelectEventArgs e) method code, may be something wrong with that section
The issue was resolved by commenting out the line // if (!Page.IsPostBack). It looks like the data source is lost somehow during the postback. The whole seems to be a local bug with ViewState, because this behavior was not observed by other users. My special thanks to Tim Schmelter and naveen.
You can keep Page.IsPostBack in Page_Load, I was having the same issue and it turns out the grid was not in ViewState in my case. If you use Linq query in your controller you will want to add this property to the grid so it will keep refreshing properly:
<asp:Panel EnableViewState="True">