I have a asp:gridview with a header and paging but I'm wonderig that the vertical border to the left of the header is missing as shown in the image below (it is to the left of the string "Postnummer"):
As it can be seen it is only this little part of the gridview that is missing - every other border works correctly.
The declaration of the gridview is as follows:
<asp:GridView ID="gvPost" AutoGenerateColumns="False"
EnableViewState="true"
EmptyDataText="Listen er tom!" runat="server" CellPadding="4"
ForeColor="#333333" Font-Size="Small" AutoPostBack="True"
CssClass="Gridview"
DataKeyNames="Postnummer"
DataSourceID="odsRecords"
AllowPaging="true"
OnPageIndexChanging="gvPost_PageIndexChanging"
AllowSorting="True"
PageSize="50" GridLines="Both"
ShowFooter="false" OnRowDataBound="gvPost_RowDataBound">
So what can I do to show this part of the vertical border?
I hope that someone can give me a hint.
Thanks in advance
Michael
you should do it in the background like below
protected void gvPost_RowDataBound(object sender, GridViewRowEventArgs e)
{
foreach (TableCell tc in e.Row.Cells)
{
tc.Attributes["style"] = "border-color: #000000";
}
}
The solution is as follows:
protected void gvPost_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[0].Style.Add("border-left-color", "#000000");
}
}
Related
I'm trying to create a Telerik grid where one of the columns contain a button that clicking it performs a certain action.
This is my definition of the grid in ASP:
<sq:Grid runat="server" CssClass="Master" ID="ReportGrid" DataSourceID="WorkPackageDS"
CellSpacing="0" GridLines="None" PageSize="100" AllowSorting="True" OnItemCommand="CancelWorkPackage_OnItemCommand"
AllowCustomPaging="True" AutoGenerateColumns="False" EnableViewState="False">
And this is the button I added:
<sq:GridTemplateColumn FilterImageToolTip="סינון" HeaderText="ביטול חבילת עבודה" UniqueName="btnCancelWO">
<ItemTemplate>
<asp:ImageButton runat="server" ID="btnCancel" ImageUrl="~/Shared Resources/imaes/tasksButton.png"
CommandName="CancelWO" CssClass="GridImageButton">
</asp:ImageButton>
</ItemTemplate>
</sq:GridTemplateColumn>
The "sq" is just something in my company, but it means a Telerik object.
This is my C# code of the function:
public void CancelWorkPackage_OnItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName == "CancelWO")
{
if (e.Item is GridDataItem)
{
GridDataItem gridDataItem = e.Item as GridDataItem;
string WFGUI = gridDataItem.FindControl("GUI").ToString();
int WorkflowInstanceId = Int32.Parse(gridDataItem.FindControl("fldIWfId").ToString());
RoadsManager.Instance.CancelWorkPackage(WFGUI, WorkflowInstanceId);
RoadsManager.Instance.LogCancellation(new[] { WorkflowInstanceId }, CurrentActivityId, CurrentUserId);
SignManager.Instance.DownloadPermitsFromSSRS(WorkflowInstanceId, WorkflowAPI.Instance.GetWorkflowVariable<object>(WorkflowInstanceId, "ReportName").ToString());
ShowAlert("חבילת עבודה ואישורים בוטלו בהצלחה", 400, 150, "הודעה חשובה");
}
}
}
I added breakpoint in the beginning of the C# function (on the if) and the program doesn't even enter the function.
What am I doing wrong?
Can anyone give me a tip what to change?
Thank you in advance
I changed the entire column from GridTemplateColumn to GridButtonColumn and now it works fine.
Code Behind
public void lbDelete_Click(object sender, EventArgs e)
{
LinkButton lb = sender as LinkButton;
GridViewRow gvrow = lb.NamingContainer as GridViewRow;
gvsize.DeleteRow(gvrow.RowIndex);
}
GridView:
<asp:GridView ID="gvsize" runat="server" ShowFooter="True" CellPadding="1" CellSpacing="2" AutoGenerateColumns="false" GridLines="Horizontal">
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:LinkButton ID="lnkdelete" runat="server" ForeColor="Blue" OnClick="lbDelete_Click">Delete</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</asp:GridView >
There are 2 rows in my gridview which I need to delete the row using the function above.
It throws an error "gvsize" RowDeletingEvent was not handled properly.
Is that necessary to use OnRowDeleted/OnRowDeleting in gridview which I feel not necessary??
As stated in How to delete row from gridview?
You are deleting the row from the gridview but you are then going and
calling databind again which is just refreshing the gridview to the
same state that the original datasource is in.
Either remove it from the datasource and then databind, or databind
and remove it from the gridview without redatabinding.
You can use row databound event to accomplish this task.
<asp:LinkButton ID="lnkBtnDel" runat="server" CommandName="DeleteRow" OnClientClick="return confirm('Are you sure you want to Delete this Record?');"">Delete</asp:LinkButton>
and in the rowdatabound event you can have
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DeleteRow")
{
//incase you need the row index
int rowIndex = ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer).RowIndex;
//followed by your code
}
}
Try this to delete row
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
dt.Rows.RemoveAt(e.RowIndex);
GridView1.DataSource = dt;
GridView1.DataBind();
}
You can also delete row from another method using Template Column
ASPX
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton ID="imgDelete" runat="server" CommandName="deletenotice" ImageUrl="~/images/delete1.gif" alt="Delete"
OnClientClick="return confirm('Are you sure want to delete the current record ?')">
</asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
C# Code
protected void gvNoticeBoardDetails_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.ToLower().Equals("deletenotice"))
{
GridViewRow row = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
NoticeBoard notice = new NoticeBoard();
HiddenField lblCust = (HiddenField)row.FindControl("hdngvMessageId");//Fetch the CourierId from the selected record
auditTrail.Action = DBAction.Delete;
Service simplyHRClient = new Service();
MessageClass messageClass = simplyHRClient.SaveNoticeBoard(notice, auditTrail);
if (messageClass.IsSuccess)
{
this.Page.AddValidationSummaryItem(messageClass.MessageText, "save");
showSummary.Style["display"] = string.Empty;
showSummary.Attributes["class"] = "success-message";
if (messageClass.RecordId != -1)
lblCust.Value = messageClass.RecordId.ToString();
}
else
{
this.Page.AddValidationSummaryItem(messageClass.MessageText, "save");
showSummary.Style["display"] = string.Empty;
showSummary.Attributes["class"] = "fail-message";
}
//Bind Again grid
GetAllNoticeBoard();
}
}
Hope it helps you
I am working on a project using Telerik controls. I'm trying to figure out how to get the selected row index on an ItemTemplate button click event, like in the markup below:
<telerik:RadGrid ID="RadGrid1" runat="server" AllowFilteringByColumn="True"
DataSourceID="cusGrid" GridLines="None" Skin="Default" AllowPaging="True" DataKeyValue="CustomerID"
PageSize="500" AllowMultiRowSelection="True" ShowStatusBar="true" >
<MasterTableView AutoGenerateColumns="False" DataKeyNames="CustomerID" DataSourceID="cusGrid">
<RowIndicatorColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</RowIndicatorColumn>
<ExpandCollapseColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</ExpandCollapseColumn>
<Columns>
<telerik:GridTemplateColumn UniqueName="CheckBoxTemplateColumn">
<ItemTemplate>
<asp:Button runat="server" Text="Select" OnClick="SelRecord" />
</ItemTemplate>
</telerik:GridTemplateColumn>
...
Normally with a GridView I would just do something like:
protected void SelRecord(object sender, EventArgs e)
{
var gRow = (GridViewRow)(sender as Control).Parent.Parent;
var key = string.Empty;
if (gRow != null) { key = gRow.Cells[0].Text; }
}
What is the equivalent with the Telerik control?
Use the CommandArgument, and use OnCommand instead of OnClick to get the row index:
<asp:Button ID="Button1" runat="server" CommandArgument='<%#Container.ItemIndex%>' OnCommand="Button1_Command" ... />
Code-behind:
protected void Button1_Command(object sender, CommandEventArgs e)
{
GridDataItem item = RadGrid1.Items[(int)e.CommandArgument];
}
You can use CommandName="" instead of OnClick.
Also add onitemdatabound="RadGrid1_ItemDataBound" to the main telerik:RadGrid tag.
Then in the code behind:
protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
GridDataItem dataItem = e.Item as GridDataItem;
int selectedRowIndex = dataItem.RowIndex;
}
}
Looking through the Telerik documentation, it looks like you want:
var gRow = ((sender as Button).NamingContainer as GridItem).Selected;
You didn't ask about this piece, but I think this code:
if (gRow != null) { key = gRow.Cells[0].Text; }
is asking for trouble.
Although markup and code-behind are always highly coupled, directly referencing individual cells is a code smell if you ask me. I'm guessing that you want to pull "Select" out of the ASP Button in your ItemTemplate.
Can you assign an ID to your Button, and call FindControl("buttonID") to get the data you need? That will help keep your code more maintainable and readable.
<telerik:GridTemplateColumn UniqueName="IndexRow" HeaderText="#">
<ItemTemplate>
<%#Container.ItemIndex + 1%>
</ItemTemplate>
</telerik:GridTemplateColumn>
something like this in Button click event should work
foreach (GridDataItem item in RadGrid1.SelectedItems)
{
GridDataItem item = (GridDataItem)RadGrid1.SelectedItems;
var key = string.Empty;
key = item.ItemIndex;
}
I am using visual studio 2005 c#, and doing server side coding.
I have a checkbox template in my gridview. I have tried to assign a CheckAllCB button outside the gridview, so that whenCheckAllCB is clicked, the list of checkboxes in the item template will be checked.
However, it does not work and I am not able to spot the mistake.
Below is my code for my CheckAllCB button:
protected void CheckAllCB_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)GridView1.HeaderRow.FindControl("CheckAll");
if (chk.Checked)
{
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox chkrow = (CheckBox)GridView1.Rows[i].FindControl("UserSelector");
chkrow.Checked = true;
}
}
else
{
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox chkrow = (CheckBox)GridView1.Rows[i].FindControl("UserSelector");
chkrow.Checked = false;
}
}
}
(SOLVED)
Thus I tried using a checkbox checkchange in the header template. However, when the checkbox CheckAll in header template is check changed, nothing happens in the checkboxes in the itemtemplate.
Below is my code for CheckAllCB in header template
private void ToggleCheckState(bool checkState)
{
// Iterate through the Products.Rows property
foreach (GridViewRow row in GridView1.Rows)
{
// Access the CheckBox
CheckBox cb = (CheckBox)row.FindControl("UserSelector");
if (cb != null)
cb.Checked = checkState;
}
}
protected void CheckAll_Click(object sender, EventArgs e)
{
ToggleCheckState(true);
}
protected void UncheckAll_Click(object sender, EventArgs e)
{
ToggleCheckState(false);
}
Anyone can help me identify the mistake I did in my method? Thank you
UserSelection item template:
CheckAllCB header template:
Added source code for GridView:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" ondatabound="gv_DataBound" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="CheckAllCB" runat="server" OnCheckedChanged="CheckAllCB_CheckedChanged" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="UserSelection" OnCheckedChanged="UserSelector_CheckedChanged" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You could do it on the client side. Here's how I normally do it with jQuery:
<asp:CheckBox ID='checkAll' runat='server' />
<asp:CheckBox ID='cb1' CssClass='checky' runat='server' />
<asp:CheckBox ID='cb2' CssClass='checky' runat='server' />
<script type='text/javascript'>
$(function() {
$('#<%= checkAll.ClientID %>').click(function() {
$(".checky").prop("checked", $(this).prop("checked"));
});
});
</script>
The problem is that the checkbox is declared as UserSelection in the page, but you are looking for UserSelector in codebehind.
Also, the header is declared as CheckAllCB in the page, but you are looking for CheckAll in the codebehind.
You need to change one or the other so that the names match.
I am using ASP.NET 4.0 with C# (Visual Web Developer 2010 Express).
I have successfully managed to implement a simple GridView bound to a stored procedure data source using declarative ASP.NET code as shown here:
<asp:GridView
ID="grdTrades"
runat="server"
DataKeyNames="tradeId"
EnablePersistedSelection="true"
SelectedRowStyle-BackColor="Yellow"
AllowPaging="true"
AllowSorting="true"
PageSize = "20"
AutoGenerateColumns="false"
DataSourceID="sdsTrades"
>
<Columns>
<asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" />
<asp:BoundField DataField="tradeId" HeaderText="TradeId" ReadOnly="True" SortExpression="tradeId" />
< ... more columns ... >
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsTrades" runat="server"
ConnectionString="<%$ ConnectionStrings:TradesDB %>"
ProviderName="<%$ ConnectionStrings:Trades.ProviderName %>"
SelectCommand="usp_GetTrades" SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
It works great including paging and sorting. I want to remove the SqlDataSource and use code-behind (I'm trying to put database access code in one place). So far I have this in my code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
grdTrades.SelectedIndex = 0;
DBUtil DB = new DBUtil();
grdTrades.DataSource = DB.GetTrades();
grdTrades.DataKeyNames = new string[] { "tradeId" };
grdTrades.DataBind();
}
}
// this is needed otherwise I get "The GridView 'grdTrades' fired event PageIndexChanging which wasn't handled."
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
grdTrades.PageIndex = e.NewPageIndex;
grdTrades.DataBind();
}
My declarative code now looks like:
<asp:GridView
ID="grdTrades"
runat="server"
EnablePersistedSelection="true"
SelectedRowStyle-BackColor="Yellow"
AllowPaging="true"
AllowSorting="true"
PageSize = "20"
AutoGenerateColumns="false"
OnPageIndexChanging="grdTrades_PageIndexChanging"
>
<Columns>
<asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" />
<asp:BoundField DataField="tradeId" HeaderText="TradeId" ReadOnly="True" SortExpression="tradeId" />
< ... more columns ... >
</Columns>
</asp:GridView>
The problem is when I click on a page number the page becomes blank. I would also like to implement sorting but would like to get the paging working first. Please help.
Thanks
You need to bind your GridView every time you change page.
For example:
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
grdTrades.DataSource = DB.GetTrades();
grdTrades.PageIndex = e.NewPageIndex;
grdTrades.DataBind();
}
My advice would be to store your results from DB.GetTrades() in the ViewState (or Cache) so you don't need to go to the database everytime you change page.
Sorting can become quite difficult when doing this, though.
You can always use an ObjectDataSource instead of a SqlDatasource. You can then point your ObjectDataSource to look at your DB.GetTrades() function. Sorting and Paging will work automatically.
Hope that helps.
You can create a method to for binding the grid view instead of Binding it again in Paging. By creating a method that binds the Grid View you can always call the method to Bind the grid view whenever you want.
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
BindgrdTrades();
}
private void BindgrdTrades()
{
DBUtil DB = new DBUtil();
grdTrades.DataSource = DB.GetTrades();
grdTrades.DataKeyNames = new string[] { "tradeId" };
grdTrades.DataBind();
}
}
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
grdTrades.PageIndex = e.NewPageIndex;
BindgrdTrades();
}
}
I had to make my _PageIndexChanging counter to public (I'm so new at asp.net that I have no idea why it matters). The page would through an error saying it couldn't find the class. These posts were a great help to get paging working with otherwise near verbatim logic. Thanks to all the posters for taking the time to lay it out so clearly. Here's the code I ended up with:
public partial class Requests : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
BindgrdBuilds();
}
}
private void BindgrdBuilds()
{
// Link GridView to datasource
GridView1.DataSource = BuildData.getBuilddata();
// Bind SQLDataSource to GridView after retrieving the records.
GridView1.DataBind();
}
public void GridView1_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
// increment PageIndex
GridView1.PageIndex = e.NewPageIndex;
// bind table again
BindgrdBuilds();
}
}
I stuck with AutoGenerated columns, and I'm doing some row binding to my data on the cs page that I didn't include above, but here's my asp code for the GridView:
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:GridView ID="GridView1"
OnRowDataBound="GridView1_RowDataBound"
OnPageIndexChanging="GridView1_PageIndexChanging"
runat="server"
SelectedRowStyle-BackColor="Yellow"
AllowPaging="true"
AllowSorting="true"
PageSize = "20"
AutoGenerateColumns="true"
<-- table formatting code trimmed -->
</asp:GridView>
I hope someone else can make use of this info, this thread was a great, simple example to follow. Now that paging works it's time to get real fancy and come up with a new name for GridView1 :D