Multiple asp:CommandField(s) at the same cell - asp.net

My asp:GridView has the options to edit / delete rows. I would like those two options to be in the same cell of every row that I have (currently these two options are presented in different cells).
This is the code that I have right now:
<asp:CommandField ShowEditButton='True' edittext='edit' canceltext='cancel' updatetext='update'></asp:CommandField>
<asp:CommandField ShowDeleteButton='True' DeleteText='delete' ></asp:CommandField>
Any help will be appreciated!!!

Try asp:TemplateField
and put both of your options there? I'm not sure if that will work. But have you tried it?

Try using a template column like this:
<asp:GridView ID="grid" runat="server" OnSelectedIndexChanged="grid_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button id="btnEdit" runat="server" />
<asp:Button id="btnDelete" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then you'll have to add the code for your grid_SelectedIndexChanged
protected void grid_SelectedIndexChanged(object sender, EventArgs e)
{
}

Related

Gridview in Update Panel losing alternate row colouring on page change

I have a GridView in an update panel.
The GridView is styled so that each alternate row is a different colour.
When I change page on the GridView it loses the alternate row colouring. All other styles are maintained.
If I remove the update panel the GridView keeps the alternate row colouring after changing page.
Does anyone have any idea on what may be causing this or how to fix it?
Thanks,
Neil
EDIT:
Here is the aspx code
<div id="active-logbooks" class="tab-content clearfix">
<div class="left-column">
<asp:MultiView runat="server" ID="mlvLogbooks" >
<asp:View runat="server" ID="vActiveLogbooks">
<asp:GridView PagerSettings-Mode="NextPrevious" PagerSettings-Position="Top" PagerSettings-NextPageImageUrl="~/img/right-arrow.png" PagerSettings-PreviousPageImageUrl="~/img/left-arrow.png" AllowPaging="true" runat="server" ID="gvActiveLogbooks" PageSize="5" AutoGenerateColumns="false" CssClass="lesson stripe-me" OnRowDataBound="gvActiveLogbooks_RowDataBound" OnPageIndexChanging="gvActiveLogbooks_PageIndexChanging">
<Columns>
<asp:BoundField HeaderText="Logbook number" DataField="LogbookNumber" ItemStyle-CssClass="border" ItemStyle-Width="100" />
<asp:BoundField HeaderText="Origin" DataField="Origin" ItemStyle-CssClass="border" ItemStyle-Width="100" />
<asp:BoundField HeaderText="Order Reference" DataField="OrderReference" ItemStyle-CssClass="border" ItemStyle-Width="100" />
<asp:TemplateField HeaderText="Transfer Date">
<ItemTemplate>
<asp:Literal runat="server" ID="lblTransferDate" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink runat="server" ID="lnkTransferLogbook" CssClass="border" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Previous<asp:Literal runat="server" ID="litBreaker" Text=" |" />
Next
</asp:View>
</asp:MultiView>
</div>
And this is the function that is called when the page change occurs:
protected void gvActiveLogbooks_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
HideShowGridViewPagerLinks(e.NewPageIndex);
gvActiveLogbooks.DataSource = _logbooks;
gvActiveLogbooks.PageIndex = e.NewPageIndex;
gvActiveLogbooks.DataBind();
}
Nowhere on the page is there anything done with colouring the GridView rows
protected void gvActiveLogbooks_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow)
return;
Literal transferLabel = (Literal)e.Row.Cells[(int)ActiveLogbookGridViewColumns.TransferDate].FindControl("lblTransferDate");
transferLabel.Text = _logbooks[e.Row.RowIndex].TransferDate.ToShortDateString();
HyperLink transferLink = (HyperLink)e.Row.Cells[(int)ActiveLogbookGridViewColumns.TransferLink].FindControl("lnkTransferLogbook");
transferLink.Text = TransferLinkText;
transferLink.NavigateUrl = "TransferLogbooks.aspx?id=" + Guid.NewGuid();
}
I'm guessing that some interaction between your CSS classes and the postback is messing this up. What happens if you switch to the RowStyle and AlternateRowStyle tags (example here), and reference your CSS classes using the CssClass property on those tags?

Displaying an image icon in a gridview column with a href value in asp.net

I have a gridview column in which I have one column that point to a pdf file on the file server. I need to have another column right beside this, displaying the pdf icon. The user should be able to click the icon and launch the file from the file server.
My code is:
<asp:GridView ID="gvInvoices" AutoGenerateColumns="false" runat="server" Font-Names="Arial" Font-Size="Small" Width="50%">
<Columns>
<asp:TemplateField HeaderText="File Type">
<ItemTemplate><img runat="server" src="Images/img_Pdf.gif" id="imgFileType" /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate><%#Eval("InvoiceNumber")%></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
How can I add a "NavugateURL" or href="" to the img ?
Rather than using an HTML img control, try using an ASP.Net Server control.
A good choice would be the Hyperlink Control:
Instead of:
<img runat="server" src="Images/img_Pdf.gif" id="imgFileType" />
Use:
<asp:HyperLink ID="imgFileType" ImageUrl="Images/img_Pdf.gif" NavigateUrl="" runat="server">HyperLink</asp:HyperLink>
Just set your NavigateUrl property.
you need to wrap your icon around an anchor tag, and set the href of the anchor tag using DataBinding expression Eval. This assumes your Datasource field "PDFPath" is an absolute path.
<asp:GridView ID="gvInvoices" AutoGenerateColumns="false" runat="server" Font-Names="Arial" Font-Size="Small" Width="50%">
<Columns>
<asp:TemplateField HeaderText="File Type">
<ItemTemplate><a href='<%#Eval("PDFPath")%>'> <img runat="server" src="Images/img_Pdf.gif" id="imgFileType" /></a></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate><%#Eval("InvoiceNumber")%></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
inside the RowDataBind event look for your image control and set its NavigateUrl property
protected void gvInvoices_RowDataBound(object Sender , GridViewRowEventArgs e)
{
if(e.Row.RowType==DataRow)
{
HtmlControl icon = e.Row.FindControl("imgFileType") as HtmlControl;
icon.NavigateUrl = ((MyDataType)e.Row.DataRow).PDFPath;
}
}
Note it is free hand writing so you may find some syntax errors that you should fix

Access Cell value in gridview

I thought this would be an easy one for me to figure out (or atl east find someone online who has) but I am running into issues.
I have the following code that creates my gridview:
<asp:GridView runat="server" ID="ContactsGrid" AutoGenerateColumns="False" DataSourceID="LinqContact"
CellPadding="4" ForeColor="#333333" GridLines="None" OnRowDeleting="ContactsGridView_RowDeleting" >
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:BoundField DataField="IConact_ID" Visible="false" ReadOnly="true" />
<asp:BoundField DataField="cFirstName" HeaderText="First Name" ReadOnly="True" />
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" />
</Columns>
</asp:GridView>
<asp:LinqDataSource ID="LinqContact" runat="server" ContextTypeName="TIPS.App_Data.TIPSDataContext" onselecting="LinqContact_Selecting" >
</asp:LinqDataSource>
Now on the c# side, I want to be able to pull the value from the first column (which is hidden) and use it to delete that specific record (with the onroedeleting event), but all the ways I found to pull the value, all come up null, like what would happen if I didn't have a LinqDatasource.
I have tried (and a slew of other that really didn't seem to be right, so not listed):
ContactsGrid.SelectedRow.Cells[0].Text;
ContactsGrid.Columns[0];
Thanks for any help!
Edit:
Ok, so I found that you can't get the value of a column this is hidden when you hide it using the grid. I did find a work around. If you hide the column using css instead, you can still access the colum.
<style type="text/css">
.hiddencol
{
display:none;
}
</style>
<asp:BoundField DataField="IContact_ID" ReadOnly="true" itemstyle-cssclass="hiddencol" />
I don't think that this is the prefered .net way. I found a reference to something called datakeynames which seems to be the proper way. I am going to dig into those next.
Edit #2:
I see that Maras and myself both came up with a solution for the hidden field, but I think I found the best one (cause its simple and built in).
In the gridview tag you can set the datakeynames attribute to your column (like a primary key, which is what I was storing in my hidden column) you can also store multiple columns.
<asp:GridView runat="server" ID="ContactsGrid" AutoGenerateColumns="False" DataSourceID="LinqContact" DataKeyNames="IContact_ID"
CellPadding="4" ForeColor="#333333" GridLines="None" OnRowDeleting="ContactsGridView_RowDeleting" >
you can then reference it with:
ContactsGrid.DataKeys[e.RowIndex].Value;
Try this:
void ContactsGrid_RowDeleting(Object sender, GridViewDeleteEventArgs e)
{
ContactsGrid.Rows[e.RowIndex].Cells[0];
}
See here for more details http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowdeleting.aspx#Y200
.
Edit after author's comment:
If you set it visibility to 'false' then there is nothing your browser can send you back in postback. You can use hidden field like in the second example:
<asp:GridView runat="server" ID="gv" OnRowDeleting="gv_RowDeleting" AutoGenerateColumns="false" AutoGenerateDeleteButton="true">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="hf" runat="server" Value="<%# ((YourItemType)Container.DataItem).Id %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void gv_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
HiddenField hf = (HiddenField) gv.Rows[e.RowIndex].Cells[0].FindControl("hf");
}

GridView Style based on bound data

I would like the rows of my GridView to have strikethrough based on a bound data value called IsObsolete. I tried to do this:
<RowStyle BackColor="#EFF3FB" Font-Strikeout='<%# Bind('IsObsolete') %>' />
But obviously this doesn't parse. I'd rather not do this in GridView.DataBound(). Any other ideas?
I do this by applying a style on the DataBinding event of one of my controls in a template. Example:
<asp:GridView ID="grdYourGrid" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="SomeTitle">
<ItemTemplate>
<asp:HyperLink ID="hrefYourLink" runat="server"
NavigateUrl="Somepage.aspx?id={0}"
OnDataBinding="hrefYourLink_DataBinding"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then implement the OnDataBinding event:
protected void hrefYourLink_DataBinding(object sender, System.EventArgs e)
{
HyperLink link = (HyperLink)(sender);
GridViewRow row = (GridViewRow)(link.Parent.Parent);
if ((bool)(Eval("IsObsolete"))
{
row.CssClass = "StrikeThroughStyle";
}
link.Text = HttpUtility.HtmlEncode(((int)(Eval("ID"))).ToString());
link.NavigateUrl = string.Format(link.NavigateUrl, Eval("ID").ToString());
}
This is just an quick example with a column with a link that gets modified based on the databinding as well but you should be able to get the gist of if an tweak it to suit your needs. I like doing it on the databinding because I do no binding inline in my aspx code.
Since the RowStyle element is applicable to the entire grid, the only way to accomplish what you want would be to have TemplateItems set for all columns and apply a CssClass to each column based on that same data value.
I'm not sure for your reasoning for avoiding the DataBound event for doing this as that would be the simplest way to accomplish it.
You might also try using a formatting function and itemstyles. Stealing a tidbit of code from above and changing it:
<%
public string GetObsoleteClass(string obsolete)
{
bool obs = Convert.ToBoolean(obsolete);
obs ? return "myObsoleteClass" : return "myNotObsoleteClass";
}
%>
<asp:GridView ID="grdYourGrid" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="SomeTitle">
<ItemTemplate>
<asp:HyperLink ID="hrefYourLink" runat="server"
NavigateUrl="Somepage.aspx?id={0}"
OnDataBinding="hrefYourLink_DataBinding"></asp:HyperLink>
</ItemTemplate>
<itemstyle CssClass='<%# Eval("isObsolete") %>'>
</itemstyle>
</asp:TemplateField>
<asp:boundfield
sortexpression="LastName"
datafield="LastName"
headertext="LastName">
<itemstyle CssClass='<%# Eval("isObsolete") %>'>
</itemstyle>
</asp:boundfield>
</Columns>
</asp:GridView>

Confirm delete before deleting dataview's row

I have a GridView which supports deleting. I'd like to add a pop up window with a question like 'Are you sure you want to delete this row?'.
My code:
<asp:GridView id="GridAccounts" runat="server" AutoGenerateColumns="False"
ShowFooter="True" DataKeyNames="ID"
DataSourceID="AccountDataSource" onrowcommand="GridAccounts_RowCommand">
<SelectedRowStyle BackColor="Lime" />
<Columns>
<asp:CommandField ButtonType="Image" ShowDeleteButton="True" DeleteImageUrl="~/Pictures/delete.jpg" />
<asp:TemplateField HeaderText="ID" InsertVisible="False" SortExpression="ID">
<EditItemTemplate>
<asp:Label ID="LabelAccountIDUpdate" runat="server" Text='<%# Eval("ID") %>'></asp:Label>
</EditItemTemplate>
<FooterTemplate>
<asp:Button ID="ButtonAccountIDInsert" runat="server" CommandName="Insert" Text="Insert" />
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="LabelAccountID" runat="server" Text='<%# Bind("ID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
protected void GridPaymentMethod_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
ImageButton deleteButton = (ImageButton)e.Row.Cells[0].Controls[0];
MyMoney.PaymentMethodRow row = (MyMoney.PaymentMethodRow)((System.Data.DataRowView)e.Row.DataItem).Row;
deleteButton.OnClientClick = string.Format("return confirm('Are you sure you want to delete payment method {0}?');", row.Name.Replace("'", #"\'"));
}
}
This renders as:
<input type="image" src="Pictures/delete.jpg" alt="Delete" onclick="return confirm('Are you sure you want to delete payment method Gotovina?');javascript:__doPostBack('ctl00$MainContent$GridPaymentMethod','Delete$0')" style="border-width:0px;" />
If I click OK on confirmation window, postback occurs, but nothing happens. If I comment out RowDataBound code, than delete works OK. Code whithout confirmation pop up:
<input type="image" src="Pictures/delete.jpg" alt="Delete" onclick="javascript:__doPostBack('ctl00$MainContent$GridPaymentMethod','Delete$0')" style="border-width:0px;" />
What am I doing wrong?
I believe this is an example of what you are trying to do. It's cleaner and you don't have to go nutz with the code behind.
In your code you must change ButtonType="Image" to ButtonType="Link" - then onclick="..." will be rendered without javascript:___doPostBack(...) part. And in the GridPaymentMethod_RowDataBound event set something like deleteButton.Text = "<img src=\"path_to_image\" ... />" (use html entities instead of <>).
Or you can use ImageButton with ComamndName="delete" and ConfirmButtonExtender from ASP.NET AjaxToolkit suite.
deleteButton.OnClientClick = string.Format("((!confirm('Are you sure you want to delete payment method {0}?'))?return false);", row.Name.Replace("'", #"\'"));

Resources