ASP:Imagebutton fail to post back in gridview - c#

<asp:GridView ID="gv1" runat="server" Width="100%" DataSourceID="ods1" AutoGenerateColumns="false"
DataKeyNames="FileID" HeaderStyle-Height="20px">
<Columns>
<asp:TemplateField ItemStyle-Width="25px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="imgMimeType" runat="server" CommandName="download" />
</ItemTemplate>
...
I have defined my image button as above, but for some reason row command fails to fire off when I click the button.
Strangely, linkbutton in another column works just fine.
How do I make it so that image button will fire off post back?
Row bind
Image Button imb = e.Row.FindControl("imgMimeType") as ImageButton;
if (imb != null)
{
imb.CommandArgument = file.FileID.ToString();
imb.AlternateText = imb.ToolTip = file.MimeType;
if (file.MimeType.Contains("zip"))
{
imb.ImageUrl = "~/Images/mimetypes/zip-icon.png";
}
...
Row command code
public void gv1_RowCommand(object sender, GridViewCommandEventArgs e)
{
switch (e.CommandName.ToLower())
{
case "download":
...

Try changing the imagebutton to a linkbutton temporarily just to see if it works. It's been a little since I've worked with asp.net but I remember running into an issue where events were not working on ImageButtons missing their images on certain browsers only. Does your ImageButton have an image set?

Add CausesValidation="False" to the imagebutton.
That worked for me.

Related

How can i get the textbox value in selected row in gridview

I am working on a project in c# asp.net.
I created a gridview and connected it to a database. My code is like that;
<asp:GridView ID="GridView1" runat="server"
class="table table-bordered table table-hover " AutoGenerateColumns="false" HeaderStyle-Height="40px" OnRowCommand="GridView1_RowCommand1" >
<Columns>
<asp:TemplateField HeaderText="Numune Parçası" >
<ItemTemplate>
<asp:Literal ID="Literal22" runat="server" Text='<%# Eval("Açıklama") %>'></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Analiz">
<ItemTemplate>
<asp:Literal ID="Literal112" runat="server" Text='<%# Eval("Analiz") %>'></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Tartım" ItemStyle-Width="10%">
<ItemTemplate>
<asp:TextBox id="txttartim" runat="server" class="form-control" ></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="10%"></ItemStyle>
</asp:TemplateField>
<asp:TemplateField HeaderText="Birim">
<ItemTemplate>
<asp:DropDownList ID="birimlist" class="form-control" runat="server" >
<asp:ListItem>g</asp:ListItem>
<asp:ListItem>mg</asp:ListItem>
<asp:ListItem>ml</asp:ListItem>
<asp:ListItem>cm2</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Kaydet">
<ItemTemplate>
<asp:LinkButton ID="Btn_Indir" runat="server"
class="btn btn-primary btn-sm" Text="Kaydet" CommandName="Open" CommandArgument='<%# Eval("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#D14124" CssClass="gridheader" ForeColor="White" HorizontalAlign="Left" />
</asp:GridView>
And the code behind is like that
protected void GridView1_RowCommand1(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Open")
{
int RowIndex = ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer).RowIndex;
string name = ((TextBox)GridView1.Rows[RowIndex].FindControl("txttartim")).Text;
DropDownList bir = (DropDownList)GridView1.Rows[RowIndex].FindControl("birimlist");
string birim = bir.SelectedItem.Value;
}
}
But my problem is that i can not get the value of textbox and dropdownlist in which selected row.
The strings name and birim is null.
Give this a go:
if (e.CommandName == "Open")
{
GridViewRow selectedRow = ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer);
string name = ((TextBox)selectedRow.FindControl("txttartim")).Text;
DropDownList bir = (DropDownList)selectedRow.FindControl("birimlist");
string birim = bir.SelectedItem.Value;
}
Ok, I often just drop in a plane jane asp.net button, and I don't bother with using the GV built in commands (such as command).
However, you have a command, so you can trigger the "row" command as you have.
And the "row command" fires before the selected index fires, and in fact fires before the selected index triggers.
I note that you passing the "ID". It not really necessary, since a GV has what is called DataKeys feature. That feature lets you get the row (database) PK id, but REALLY nice is you don't have to expose, show, or even use a hidden field, or anything else to get that data key. (this is great for several reasons - one being that you don't have to hide or shove away, or even use the command argument to get that database PK row. The other HUGE issue is then your database pk values are NEVER exposed client side - so nice for security).
Ok, So, make sure your row event is being triggered, and you should be able to use this, first the markup for the Linkbutton:
<asp:TemplateField HeaderText="View" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:LinkButton ID="cmdView" runat="server" Text="View" CommandName="Open" cssclass="btn btn-info" />
</ItemTemplate>
</asp:TemplateField>
Note how I do NOT worry or pass the "ID". As noted, datakeys takes care of this, and in the GV def, we have this:
<asp:GridView ID="GVHotels" runat="server" class="table"
AutoGenerateColumns="false" DataKeyNames="ID"
bla bla bla
So, now our code is this:
protected void GVHotels_RowCommand(object sender, GridViewCommandEventArgs e)
{
LinkButton lBtn = e.CommandSource as LinkButton;
GridViewRow gRow = lBtn.NamingContainer as GridViewRow;
int PKID = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
Debug.Print("Row index click = " + gRow.RowIndex);
Debug.Print("Database PK id = " + PKID);
// get combo box for this row
DropDownList cbo = gRow.FindControl("cboRating") as DropDownList;
Debug.Print("Combo box value = " + cbo.SelectedItem.Value);
Debug.Print("Combo box Text = " + cbo.SelectedItem.Text);
Output:
Row index click = 7
Database PK id = 68
Combo box value = 2
Combo box Text = Good
So, use datakeys - you thus DO NOT have have to put in extra attributes here and there and everywhere to get the PK row value.
In fact, really, using row command is often MORE of a pain, and you can DUMP the command name to trigger that button click. And REALLY nice then is you get a separate nice command "code stub" for each button (or link button) in the GV. (no need to try and shove all that code into the row command, and then a bunch of if/then or "case" statements to run code for a given command.
So, I in fact suggest you use this:
<asp:TemplateField HeaderText="View" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:LinkButton ID="cmdView" runat="server" Text="View"
OnClick="cmdView_Click1" cssclass="btn btn-info" />
</ItemTemplate>
</asp:TemplateField>
So, all we did was add a plane jane good old regular click event. It will not fire row command, and in fact will not trigger "selected index changed" for the GV, but in most cases I don't need them. So, now, if you 2 or 5 buttons, you just think of them as plane jane regular buttons. (just type in onclick in teh markup, and choose "create new event" that intel-sense pops up). So, now our code for the button is seperate, and not part of the row command. Our code thus becomes this:
protected void cmdView_Click1(object sender, EventArgs e)
{
LinkButton lBtn = sender as LinkButton;
GridViewRow gRow = lBtn.NamingContainer as GridViewRow;
int PKID = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
Debug.Print("Row index click = " + gRow.RowIndex);
Debug.Print("Database PK id = " + PKID);
// get combo box for this row
DropDownList cbo = gRow.FindControl("cboRating") as DropDownList;
Debug.Print("Combo box value = " + cbo.SelectedItem.Value);
Debug.Print("Combo box Text = " + cbo.SelectedItem.Text);
}
So, I tend to not bother with row command - better to just have that plane jane click event. Note the use of naming container - but the rest of the code is the same. I would ONLY use "commandName" to trigger the row event, since THEN the gv index changed event fires - and that useful for highlighting the whole row - but if you don't care, then don't even bother with CommandName - just use regular click events, and as noted, this is even better, since then each button gets it 100% own nice little code stub like any other button click tends to have.
So I grabbed a dropdownlist but your code could be say this:
TextBox tBox = gRow.FindControl("txttartim") as TextBox;
debug.Print (tBox.Text);
I solve the problem.
When i write the code in the Page_load section, it works! It is not null anymore.
if (!Page.IsPostBack)
{
load();
..
}

checking checkbox state which is inside Dataitemtemplate devexpress gridview when button is clicked from code behind

I wanto check the state of checkbox which is inside the data item template in devexpress grid view when the user click the ok button
here is my aspx code for gridviewColumn
<Columns>
<dx:GridViewDataColumn Caption="Data Source" FieldName="dataSrc" VisibleIndex="1"></dx:GridViewDataColumn>
<dx:GridViewDataColumn Caption="Download" FieldName="dwnloadConfig" VisibleIndex="2" Width="70px" >
<DataItemTemplate>
<dx:ASPxCheckBox ID="cbDwnloadConfig" ClientInstanceName="cbDwnloadConfig
" runat="server" >
</dx:ASPxCheckBox>
</DataItemTemplate>
</Columns>
Now when ok button is clicked i want to check the state of cbDwnloadConfig on server side
I used following code on cs file to access the dataitem template control but the checked state is always false.
ASPxCheckBox cbDwnload = gvDataSrc.FindRowCellTemplateControl(rwIndex[i], gvDataSrc.Columns["dwnloadConfig"] as GridViewDataColumn, "cbDwnloadConfig") as ASPxCheckBox;
So what is the proper way to check the state of checkbox which is inside the dataitemtemplate?
It may be that you are binding your grid view in PageLoad method and that may cause this behaviour.
You should bind your grid view in following way
if(!page.IsPostBack)
{
//BIND YOUR GRID
}
Above will prevent rebinding of gridview when button is clicked.
Well for those of you having the same issue i have found solution to the problem,
I had to use callback for this issue.
<Columns>
<dx:GridViewDataColumn Caption="Data Source" FieldName="dataSrc" VisibleIndex="1"></dx:GridViewDataColumn>
<dx:GridViewDataColumn Caption="Download" FieldName="dwnloadConfig" VisibleIndex="2" Width="70px" >
<DataItemTemplate>
<dx:ASPxCheckBox ID="cbDwnloadConfig" ClientInstanceName="cbDwnloadConfig" runat="server" >
<ClientSideEvents CheckedChanged="function(s,e)
{dwnloadSrc.PerformCallback(s.GetChecked());
}"></ClientSideEvents>
</dx:ASPxCheckBox>
</DataItemTemplate>
</Columns>
C#
protected void dwnloadSrc_OnCallback(object source, CallbackEventArgs e)
{
var param = e.Parameter;
//now check the paramater
//and do your magic
}
you also can pass two or multiple parameter at once from the front end/aspx
for that just do this:
dwnloadSrc.PerformCallback(s.GetChecked()+'_'+ gv.FocusedRowsIndex())
and at the Code behind you can check the parameter :
var param = e.Parameter;
var newParam = param.Split('_');
bool state = Convert.ToBoolean(newParam[0]);
int rwIndex = Convert.ToInt32(newParam[1]);
Thanks!

How to get datatextfield value

I am making a web site in visual studio 2012, using asp.net, c#.
I created a grid view, which is taking data from my sql server, and created a button field which is bound to id_p, which is one of the collumns taken from a database. I am trying to get the data of the id_p for the row in which the button was clicked.
<asp:ButtonField ButtonType="Button" DataTextField="id_p"
DataTextFormatString="Stavi u košaricu" Text="Button1" />
What I need is not the selected row, only the id_p value, so how could I do that, please?
You need to handle the OnRowCommand Event on the gridview as so:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView_RowCommand"
And create a ItemTemplateField to display a regular <asp:button> instead of using the ButtonField column:
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btn" runat="server"
CommandName="Something" CommandArgument='<%#Eval("id_p") %>'
Text="Stavi u košaricu" />
</ItemTemplate>
</asp:TemplateField>
Now you handle the RowCommand Event:
protected void GridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
string m_id = e.CommandArgument.ToString();
if (e.CommandName == "Something")
{
//do something with m_id
}
}

Full postback triggered by LinkButton inside GridView inside UpdatePanel

I have a GridView inside of a UpdatePanel. In a template field is a button I use for marking items. Functionally, this works fine, but the button always triggers a full page postback instead of a partial postback. How do I get the button to trigger a partial postback?
<asp:ScriptManager ID="ContentScriptManager" runat="server" />
<asp:UpdatePanel ID="ContentUpdatePanel" runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:GridView ID="OrderGrid" runat="server" AllowPaging="false" AllowSorting="false"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:LinkButton ID="MarkAsCompleteButton" runat="server" Text="MarkAsComplete"
CommandName="MarkAsComplete" CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="LoadDate" HeaderText="Load Date" />
<asp:BoundField DataField="EmployeeCutOffDate" HeaderText="Cut Off Date" />
<asp:BoundField DataField="IsComplete" HeaderText="Is Completed" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
You need to register each and every LinkButton as an AsyncPostBackTrigger. After each row is bound in your GridView, you'll need to search for the LinkButton and register it through code-behind as follows:
protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);
}
This also requires that ClientIDMode="AutoID" be set for the LinkButton, as mentioned here (thanks to Răzvan Panda for pointing this out).
It's probably not advised but you can make everything on the GridView work asynchronously by excluding the EventName on the AsyncPostBackTrigger so e.g.
<Triggers>
<asp:AsyncPostBackTrigger ControlID="OrderGrid" />
</Triggers>
This will make the RowCommand event and any other event on the GridView fire asynchronously. Note as well that when you make ClientIDMode="Static" on the GridView it will cause a full postback.
My grid view is in conditional mode.
protected void gvAgendamentoExclui_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
LinkButton lnk = e.Row.FindControl("LinkButton2") as LinkButton;
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = lnk.UniqueID;
trigger.EventName = "Click";
UpdatePanel2.Triggers.Add(trigger);
}
}
And in the click event of the linkbutton I put:
protected void LinkButton2_Click(object sender, EventArgs e)
{
UpdatePanel2.Update();
}
Put the following element inside system.web element in web.config file
<xhtmlConformance mode="Transitional"/>
MSDN specifies that the UpdatePanel.ChildrenAsTriggers property "[g]ets or sets a value that indicates whether postbacks from immediate child controls of an UpdatePanel control update the panel's content" (see http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.childrenastriggers.aspx).
Since your LinkButton does not appear to be an "immediate child control," then I would recommend configuring your LinkButton as an explicit AsyncPostBackTrigger.
Below your </ContentTemplate> tag, try adding this:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>
I had an issue where I had one form working fine (page1), another doing whole post backs (page2). Turned out when I made the 2nd page, I had done a bit too much cut/paste, and it still had a javascript call in the form definition.
< form id="form1" runat="server" onsubmit="return checkstuff();">
But checkstuff was not defined in page 2.
deleted the onsubmit, and the partial posts started working.
In the working page - page 1, checkstuff was defined, but was just a stub, which did nothing more than return true. Just for grins, I put an alert in checkstuff, and sure enough, it is called for all submits, partial or not. And, if I changed the stub to just return false, nothing happened at all.
Point in all this, the javascript is still exercised, as if a full page is being submitted. So double check your client side scripts.
this may be old but my solution was to put an update panel inside the itemTemplate and one outside the gridview as well.
the trigger should be the gridview and the outside trigger should be the gridview and PageIndexChanging. Try that.
You need to register each controls for each RowState.
1: Register your controls for RowState = Alternate and Normal)
2: Register your controls for RowState = Edit
3: ...
ASPX:
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:LinkButton runat="server" ID="Btn1"
CommandName="Edit" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-pencil-square-o"></i></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="Btn2" runat="server" CommandName="Update" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-check"></i></asp:LinkButton>
</EditItemTemplate>
</asp:TemplateField>
Code behind :
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow
&& (e.Row.RowState == DataControlRowState.Normal
|| e.Row.RowState == DataControlRowState.Alternate))
{
LinkButton Btn1 = e.Row.FindControl("Btn1 ") as LinkButton;
ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn1 );
}
if (e.Row.RowType == DataControlRowType.DataRow
&& e.Row.RowState == DataControlRowState.Edit)
{
LinkButton Btn2 = e.Row.FindControl("Btn2 ") as LinkButton;
ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn2 );
}
}

Programmatically access GridView columns and manipulate

I have a GridView :
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" GridLines="None"
HorizontalAlign="Left" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1" onrowcommand="GridView1_RowCommand1">
<HeaderStyle HorizontalAlign="Left" />
<Columns>
<asp:TemplateField HeaderStyle-Width="150">
<HeaderTemplate>
<b>Downloads</b>
</HeaderTemplate>
<ItemTemplate>
<!-- <asp:HyperLink ID="hyperlinkDownload" runat="server" NavigateUrl="" >Download
MP3</asp:HyperLink> -->
<asp:LinkButton CommandName="download"
CommandArgument='<%# Eval("Name") %>' runat="server">Download MP3</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</asp:GridView>
I want to query the value of a particular field in a DB and if it's true, display the LinkButton. if false, I want the linkButton not to be displayed.
is there a way to access the GridView programmatically and make visible certain of its columns or manipulate its items ?
help.
You can do this by adding a handler to the RowDataBound event. Add an event handler along this lines of this in your code behind:
protected void myGrid_RowDataBound(Object sender, GridViewRowEventArgs e)
{
var data = e.Row.DataItem as DataRowView;
if (data != null)
{
var lbtDownload = e.Row.FindControl("lbtDownload");
lbtDownload.Visible = (bool) data.Row["HasFileForDownload"];
}
}
In your markup, attach the event handler to the grid:
<asp:GridView OnRowDataBound="myGrid_RowDataBound" ...>
You will also need to assign an id to the LinkButton, matching the one that you are search for using the FindControl() method in the event handler.
Disclaimer: I am on currently a Linux machine with no chance of testing this. Please report any bugs in the code - feel free to correct them if you have editor rights.
Yes there is.
1) You need to subscribe the RowDataBound event.
2) Give the LinkButton an ID.
3) Insert in codebehind
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton _bt = e.Row.FindControl("ID") as LinkButton;
if(_bt != null)
{
// have a look at the e.row.DataItem and try to get the value of your desired visibility property
_bt.Visible = true;
}
}
}
4) If this does not work with accessing the DataItem, start thinking about a LinqDataSource.

Categories