Open new dynamic window within gridview dataview? - asp.net

I have a gridview (called grdSearchResults) that contains links to pdfs. The pdf url's are returned from the database but I'm not sure how to add the url to an imagebutton control within the gridview.
Here's my codebehind:
List<SearchResults> search = _searchRepository.GetFactFileSearchResults(results);
grdSearchResults.DataSource = search;
grdSearchResults.DataBind();
And here's my aspx page code:
<asp:TemplateField HeaderText="FILE TYPE" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton runat="server" ID="_imgbtnPreview" OnClientClick="<%# Container.DataItem("DownloadUrl") %>" ImageUrl="~/images/fileType_pdf.png" />
</ItemTemplate>
But this thows an error ("The server tag is not well formed") Any idea how to fix this? Thanks

I assume you want to call a javascript function OnClientClick. But you haven't showed us it so it's difficult to help.
You can also set the ImageButton's ImageUrl in RowDataBound (which i normally prefer):
protected void grdSearchResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView rv = (DataRowView) row.DataItem;
ImageButton imgbtnPreview = (ImageButton)e.Row.FindControl("_imgbtnPreview");
imgbtnPreview.ImageUrl = rv.Row.Field<String>("DownloadUrl");
}
}

Your OnClientClick should be using single quote in the outer
OnClientClick='<%# Container.DataItem("DownloadUrl") %>'
And the image can be
<asp:Image runat="server" ID="x" ImageUrl='<%# String.Format("~/{0}", Eval("ImageUrl")) %>' />

Related

Conditionally show hide asp linkbutton

I have below link button and I need to show it only if grid has records.
<asp:LinkButton ID="linkButton1" runat="server" ToolTip="Delete file" Visible='<%# (Convert.ToInt32(Eval("gridViewFileInformation.Rows.Count"))>0) %>' >Delete</asp:LinkButton>
But it shows always.
In your code behind file after databind of "gridViewFileInformation" you can set the Visible property of linkButton1. Similar question
Something like:
ASPX File:
<asp:GridView
runat="server"
ID="gridViewFileInformation"
OnDataBound="gridViewFileInformation_DataBound">
</asp:GridView>
CS File:
protected void gridViewFileInformation_DataBound(object sender, EventArgs e)
{
linkButton1.Visible = (gridViewFileInformation.Rows.Count > 0);
}

MaskedEditExtender is not working from 2nd line in gridview in Asp.Net

I have a gridview on my page, there is three columns, one is for quantity, i need to use MaskEditExtender with simple TextBox, but it is working only on first row, from second row the textbox is appearing without mask.
here is my code :
<Columns>
<asp:TemplateField HeaderText="Qty">
<ItemTemplate>
<asp:TextBox ID="txtQuan" runat="server" ValidationGroup="MKE" MaxLength="5"
style="text-align:right" width="100px" Text='<%# BIND("QUAN") %>' />
<ajaxToolkit:MaskedEditExtender ID="txtQuan_MaskedEditExtender" runat="server"
Enabled="True" Mask="99999" TargetControlID="txtQuan" />
</ItemTemplate>
</asp:TemplateField>
Reason is that When Gridview Render row each Row contain textbox with deffferent autogenerated id and you are given a fixed name in TargetControlID Property in MaskEditExtender . so you need to use RowDataBound Event to Put MaskEditExtender in each textbox....
using AjaxControlToolkit; protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
TextBox txt = (TextBox)e.Row.FindControl("txtQuan");
MaskedEditExtender mxt = (MaskedEditExtender)e.Row.FindControl("MaskedEditExtender1");
mxt.TargetControlID = txt.ID;
}
}

Using hyperlink with querystring for gridview row

Is there someway to turn the row of a gridview into a hyperlink so that when a user opens it in a new tab for example, it goes to that link? Right now I am using a LinkButton and when the user opens it in a new tab, it doesn't know where to go.
I figured the .aspx code would look something like:
<asp:TemplateField>
<ItemTemplate>
<Hyperlink ID="hyperlink" runat="server" ForeColor="red" HtmlEncode="false" navigationURL="testUrl.aspx"
</ItemTemplate>
</asp:TemplateField>
The only thing is, our URLs are set up in the C# code behind as a query string, so I'm not sure how to pass that into the navigationURL section.
I'm guessing there's something I can do on the page_load with the query string to redirect to the page I need, but this is my first time working with query strings so I'm a little confused.
Thanks!
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#String.Format("~/controller.aspx?routeID1={0}&routeID2={1}", Eval("routeid1"), Eval("routeid2"))%>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
routeid1 and routeid2 are passed as query strings to the controller of that page.
What I did recently is modified my class to have a readonly property that constructs the A tag for me. This way I have control over what gets displayed; just text or a link.
<ItemTemplate>
<asp:Label ID="ColumnItem_Title" runat="server" Text='<%# Bind("DownloadATag") %>'> </asp:Label>
</ItemTemplate>
The code behind just binds an instance of the class to the gridview. You can bind the gridview whenever, on load on postback event, etc.
Dim docs As DocViewList = GetViewList()
GridViewDocuments.DataSource = docs
GridViewDocuments.DataBind()
In the above code, the DocViewList, instantiated as docs, is a list of a class that has all the properties that are needed to fill my GridView, which is named GridViewDocuments here. Once you set the DataSource of your GridView, you can bind any of the source's properties to an item.
Something like:
<asp:LinkButton ID="LinkButton_Title" runat="server" target="_blank"
PostBackUrl='<%# Eval(Request.QueryString["title"]) %>'
or binding them from the RowCreated event:
protected void GridView_OnRowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
(e.Row.FindControl("LinkButton_Title") as LinkButton).PostBackUrl = Request.QueryString["title"]))
}
}

How to programmatically reach any AspxControl inside an AspXGridView's EditItemTemplate

Its very simple and i feel myself as an idiot :(
I newly started to using DevX Controls. Its documentation and sample projects are SUCKS!
My problem is:
I have an ASPxGridView on my aspx page:
<dx:ASPxGridView ID="dxdgMyGrid" runat="server" AutoGenerateColumns="False" OnStartRowEditing="DxGridStartRowEditing">
<SettingsEditing Mode="PopupEditForm" PopupEditFormHeight="200px" PopupEditFormWidth="500px"
EditFormColumnCount="2" PopupEditFormHorizontalAlign="Center" PopupEditFormVerticalAlign="Middle"
PopupEditFormModal="true" />
<Columns>
<dx:GridViewDataTextColumn FieldName="MyField1" VisibleIndex="1">
<EditFormSettings VisibleIndex="0" />
<EditItemTemplate>
<dx:ASPxDateEdit ID="dxdateMyField1" runat="server">
</dx:ASPxDateEdit>
</EditItemTemplate>
</dx:GridViewDataTextColumn>
<dx:GridViewDataColumn FieldName="MyField2" VisibleIndex="4">
<EditFormSettings VisibleIndex="1" />
<EditItemTemplate>
<dx:ASPxComboBox ID="dxcomboMyField2" runat="server">
</dx:ASPxComboBox>
</EditItemTemplate>
</dx:GridViewDataColumn>
</Columns>
How can i reach dxdateMyField1 or dxcomboMyfield2 on ASPX.CS file? I want to write:
dxcomboMyField2.DataSource = GetMyData2List();
dxcomboMyField2.SelectedItemIndex = 0;
... etc.
Thanks a lot.
You cannot access the EditItemTemplate Control Directly. You can access them at the HtmlRowCreated event as:
if (e.RowType != GridViewRowType.InlineEdit) return;
ASPxTextBox txtBox = ASPxGridView1.FindEditRowCellTemplateControl(ASPxGridView1.Columns["Name"]
as GridViewDataColumn, "ASPxTextBox1") as ASPxTextBox;
Check the documentation on Accessing Controls Contained within Templates
It is possible to cast the ASPxLabel.NamingContainer property to GridViewEditItemTemplateContainer and get a column value via the GridViewEditItemTemplateContainer.Text property.
But I like the technique of using the Init/Load event handler.When the grid switches to edit mode, the ASPxLabel.Load event is raised. Check this article The general technique of using the Init/Load event handler for implementation help.
[ASPx]
<dxe:ASPxTextBox ID="txtName" runat="server" Width="170px" OnInit="txtName_Init">
</dxe:ASPxTextBox>
[C#]
ASPxTextBox txtName;
protected void txtName_Init(object sender, EventArgs e)
{
txtName = (ASPxTextBox)sender;
GridViewEditFormTemplateContainer container = txtName.NamingContainer as GridViewEditFormTemplateContainer;
// You can remove the if statement, and try to insert a new record. You'll catch an exception, because the DataBinder returns null reference
if (!container.Grid.IsNewRowEditing)
txtName.Text = DataBinder.Eval(container.DataItem, "CategoryName").ToString();
}
Update Event:
protected void grid_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e)
{
e.NewValues["CategoryName"] = txtName.Text;
}
There is already an question - ASPxGridView - How to find a control inside the EditItemTemplate on DevExpress fourm .
You can use combo box init/load event handler for setting combo datasource. If that doesn't work for you, use FindEditRowCellTemplateControl (use link in comments for further explanation).

Passing multiple argument through CommandArgument of Button in Asp.net

I have a gridview with multiple rows, each has a Update button and I need to pass 2 values when someone clicks on Update button.
Aside from packing the arguments inside CommandArgument separated by commas (archaic and not elegant), how would I pass more than one argument?
<asp:LinkButton ID="UpdateButton" runat="server" CommandName="UpdateRow" CommandArgument="arg_value" Text="Update and Insert" OnCommand="CommandButton_Click" ></asp:LinkButton>
As a note, the values can't be retrieved from any controls on the page, so I am presently not seeking any design solutions.
You can pass semicolon separated values as command argument and then split the string and use it.
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:LinkButton ID="lnkCustomize" Text="Customize" CommandName="Customize" CommandArgument='<%#Eval("IdTemplate") + ";" +Eval("EntityId")%>' runat="server">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
at server side
protected void gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
string[] arg = new string[2];
arg = e.CommandArgument.ToString().Split(';');
Session["IdTemplate"] = arg[0];
Session["IdEntity"] = arg[1];
Response.Redirect("Samplepage.aspx");
}
After poking around it looks like Kelsey is correct.
Just use a comma or something and split it when you want to consume it.
#Patrick's answer is a good idea, and deserves more credit!. You can have as many data items as you want, they are all separated, and can be used client side if necessary.
They can also be added declaratively rather than in code. I just did this for a GridView like this:
<asp:TemplateField HeaderText="Remind">
<ItemTemplate>
<asp:ImageButton ID="btnEmail"
data-rider-name="<%# ((Result)((GridViewRow) Container).DataItem).Rider %>"
data-rider-email="<%# ((Result)((GridViewRow) Container).DataItem).RiderEmail %>"
CommandName="Email" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/images/email.gif" />
</ItemTemplate>
</asp:TemplateField>
In the RowCommand, you do this:
void gvMyView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Email")
{
var btnSender = (ImageButton)e.CommandSource;
var riderName = btnSender.Attributes["data-rider-name"];
var riderEmail = btnSender.Attributes["data-rider-email"];
// Do something here
}
}
So much cleaner than hacking all the values together with delimiters and unpacking again at the end.
Don't forget to test/clean any data you get back from the page, in case it's been tampered with!
My approach is using the attributes collection to add HTML data- attributes from code behind. This is more inline with jquery and client side scripting.
// This would likely be done with findControl in your grid OnItemCreated handler
LinkButton targetBtn = new LinkButton();
// Add attributes
targetBtn.Attributes.Add("data-{your data name here}", value.ToString() );
targetBtn.Attributes.Add("data-{your data name 2 here}", value2.ToString() );
Then retrieve the values through the attribute collection
string val = targetBtn.Attributes["data-{your data name here}"].ToString();
A little more elegant way of doing the same adding on to the above comment ..
<asp:GridView ID="grdParent" runat="server" BackColor="White" BorderColor="#DEDFDE"
AutoGenerateColumns="false"
OnRowDeleting="deleteRow"
GridLines="Vertical">
<asp:BoundField DataField="IdTemplate" HeaderText="IdTemplate" />
<asp:BoundField DataField="EntityId" HeaderText="EntityId" />
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:LinkButton ID="lnkCustomize" Text="Delete" CommandName="Delete" CommandArgument='<%#Eval("IdTemplate") + ";" +Eval("EntityId")%>' runat="server">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</asp:GridView>
And on the server side:
protected void deleteRow(object sender, GridViewDeleteEventArgs e)
{
string IdTemplate= e.Values["IdTemplate"].ToString();
string EntityId = e.Values["EntityId"].ToString();
// Do stuff..
}
Either store it in the gridview datakeys collection, or store it in a hidden field inside the same cell, or join the values together. That is the only way. You can't store two values in one link.
If you want to pass two values, you can use this approach
<asp:LinkButton ID="RemoveFroRole" Text="Remove From Role" runat="server"
CommandName='<%# Eval("UserName") %>' CommandArgument='<%# Eval("RoleName") %>'
OnClick="RemoveFromRole_Click" />
Basically I am treating {CommmandName,CommandArgument} as key value. Set both from database field. You will have to use OnClick event and use OnCommand event in this case, which I think is more clean code.

Resources