Using event of control under datalist - asp.net

I have a datalist control which some controls(ex: button) are in it. I want to write some code into click event of button which is in the datalist control. But in the code behind page I can't see the name of controls into datalist. How can I solve this problem?

Attach your event to the controls in the OnItemCreated event of the datalist.
EDITED TO ADD SAMPLE
private void DataList_ItemCreated(object sender,
System.Web.UI.WebControls.DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Button btn = (Button)e.Item.FindControl("btnWhatever");
if (btn != null) btn.Click += new EventHandler(SomHandler);
}
}

If you don't want to add a handler to all the child events, you could instead add your code to the OnItemCommand.
<asp:DataList id="DataList1" runat="server">
<ItemTemplate>
<asp:Button ID="btnDoSomething" Runat=server CommandName="DoSomething"
CommandArgument="<%# DataBinder.Eval(Container.DataItem, "SomeID")
%>"></asp:LinkButton>
</ItemTemplate>
</asp:DataList>
protected void DataList1_ItemCommand(
object source, DataListCommandEventArgs e)
{
if (e.CommandName == "DoSomething")
{
//Do stuff
}
}

Related

Change GridView Custom Button Text and Css on click event

I am working on a project where I am creating a dashboard for the Admin.
I have a UsersGridView which displays the data of the registered users in it.
Using the Template field for the Gridview I have created a button for that allows the Admin to with Lockout or Enable the user's to use the system.
<asp:TemplateField HeaderText="LockoutStatus">
<ItemTemplate>
<asp:Button ID="LockoutStatus" runat="server" CausesValidation="false" CommandName="LockoutStatus" Text="Enabled"
CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
In the RowCommand event how can I change the button CssClass and text if the user is locked out from the system.
There are several ways you can change the CssClass.
With the RowDataBound event.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is d datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//cast the row back to a datarowview
DataRowView row = e.Row.DataItem as DataRowView;
//use findcontrol to locate the butotn
Button btn = e.Row.FindControl("LockoutStatus") as Button;
//change the class based on a column value
if (row["ColumnName"].ToString() == "LockedOut")
{
btn.CssClass = "ClassA";
}
}
}
Or on the aspx page with a ternary operator.
<asp:Button ID="LockoutStatus" runat="server"
CssClass='<%# Eval("ColumnName").ToString() == "LockedOut" ? "ClassA" : "ClassB" %>'
Or as you wanted in the RowCommand event. You can use the CommandSource and cast it to a Button.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
Button btn = e.CommandSource as Button;
btn.CssClass = "ClassA";
}

Radio Button inside grid view control not firing oncheckedchanged event

I have following code in my application I have a gridview control insde my grid view I have radio button defined as templetefield.
<asp:View ID="View3" runat="server">
<script type = "text/javascript">
function RadioCheck(rb) {
var gv = document.getElementById("<%=grdAllPartsRequestList.ClientID%>");
var rbs = gv.getElementsByTagName("input");
var row = rb.parentNode.parentNode;
for (var i = 0; i < rbs.length; i++) {
if (rbs[i].type == "radio") {
if (rbs[i].checked && rbs[i] != rb) {
rbs[i].checked = false;
break;
}
}
}
}
</script>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="rbSelected" runat="server" AutoPostBack="True"
oncheckedchanged="rbSelected_CheckedChanged" GroupName="RequestSelection" onclick="RadioCheck(this);" />
<asp:HiddenField ID="HiddenField1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</<asp:View>
Code Behind .CS
protected void rbSelected_CheckedChanged(object sender, EventArgs e)
{
}
Now my problem is upon running my page when I click the radio button the Event doesn't fire. oncheckedchanged is not firing.
Surprisingly The same functionality works fine in another page with in the grid view.
I have searched the web for this answers. But so far nothing worked out. I have Update Panel in my Master Page.. I have tried to play with UpdateMode="Always" and ChildrenAsTriggers="true" but so far nothing worked out please help!
Try this,
void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
Radiobutton rb = e.Row.FindControl("rbSelected") as Radiobutton;
rb.oncheckedchanged += this.rbSelected_CheckedChanged;
}
}
The event will be added to the radiobutton on rowdatabound event of GridView...
Hope this helps you...

add style for item in datalist

I had Datalist and I want to give item style when I click on it to show user the he select this item I did my code but when I selected item It didnot have any style
protected void DataList3_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
e.Item.Attributes["onmouseover"] = "this.style.cursor='hand';this.style.textDecoration='underline';";
e.Item.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Item.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.DataList3, "Select$" + e.Item.ItemIndex);
}
e.Item.Attributes are not rendered as html, they just don't show up. Add some kind of Control, a panel for example:
<asp:DataList ID="DataList3" runat="server">
<ItemTemplate>
<asp:Panel ID="Panel1" runat="server">
<%#Container.DataItem%>
</asp:Panel>
</ItemTemplate>
</asp:DataList>
And then alter your ItemDataBound event
protected void DataList3_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Panel p = (Panel)e.Item.FindControl("Panel1");
p.Attributes.Add("onmouseover", "this.style.cursor='hand';this.style.textDecoration='underline';");
p.Attributes.Add("onmouseout", "this.style.textDecoration='none';");
// ?? p.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.DataList3, "Select$" + e.Item.ItemIndex);
}
}
Or an even better solution for the style part of your question is using css and a classname, add <ItemStyle CssClass="item" /> to your datalist.
css:
.item{cursor:pointer;text-decoration:underline;}
.item:hover{text-decoration:none;}
The "onlick" should be handled by a LinkButton if you ask me, but I don't exactly understand what you are trying to do with that.

Why won't my LinkButton inside a GridView raise its OnClick event?

I have a LinkButton inside a GridView (via an TemplateField). No matter what I try, the LinkButton will not invoke its event handler. I have tried both:
A traditional event handler ("OnClick")
A OnRowCommand event handler at the GridView level.
In both cases, I've debugged and it doesn't even catch the event handler.
If I move the LinkButton out on the page (so it's not in the GridView), it works fine, so I know the syntax is right.
Here is the "traditional" method:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" OnClick="CancelThis" runat="server" />
</ItemTemplate>
<asp:TemplateField>
What's interesting is if I remove the "CancelThis" method from the code behind, it throws an error. So I know it's aware of its event handler, because it looks for it when it compiles.
Here is the RowCommand method:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" CommandName="CancelThis" runat="server" />
</ItemTemplate>
<asp:TemplateField>
In this case, the GridView has:
OnRowCommand="GridView_RowCommand"
It postsback, but never hints at raising the event.
Any idea what I'm missing here?
How are you binding your GridView? Are you using a datasource control? If you are binding manually during Page_Load, it's possible that since the grid is binding every round trip, the event handler isn't catching properly. If this is the case, you may want to try something like:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//do binding
}
}
Can you post sample binding code to go with your markup?
If you really want to force the issue, you could hook into the RowDataBound event on the Grid, find the button manually and add the handler in the code behind. Something like:
markup snippet:
<asp:GridView ID="gvTest" runat="server" OnRowDataBound="gvTest_RowDataBound" />
code behind:
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
//find button in this row
LinkButton button = e.Row.FindControl("DeleteButton") as button;
if(button != null)
{
button.Click += new EventHandler("DeleteButton_Click");
}
}
}
protected void DeleteButton_Click(object sender, EventArgs e)
{
LinkButton button = (LinkButton)sender;
// do as needed based on button.
}
I'm not sure what the purpose of the button is, but assuming it is a row delete button, you may not want to take this approach as in the event handler, you don't have direct access to the row in question, like you would using the RowCommand event.
Is there a reason you're using the Template field? Vs say a ButtonField? If you use a ButtonField, then you can hook into the RowCommand event.
markup snippet:
<asp:GridView ID="gvTest" runat="server" OnRowCommand="gvTest_RowCommand">
<columns>
<asp:buttonfield buttontype="Link" commandname="Delete" text="Delete"/>
....
</columns>
</asp:GridView>
code behind:
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Delete")
{
//take action as needed on this row, for example
int rowIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow currentRow = (sender as GridView).Rows[rowIndex];
//do something against the row...
}
}
You might want to consult MSDN docs on some of these topics:
RowCommandEvent
ButtonField class
EDIT:
To answer your question on the ButtonField - yes I don't see why you couldn't still deal with a buttonfield. Here's a snippet to find the buttonfield during row data bound and hide it (untested but I think would work...)
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//let's assume your buttonfield is in column 1
// (you'd know this based on your markup...)
DataControlFieldCell cell = e.Row.Cells[1] as DataControlFieldCell;
if(cell != null)
{
ButtonField field = cell.ContainingField as ButtonField;
//based on your criteria, show or hide the button
field.Visible = false;
//or
field.Visible = true;
}
}
}
Is viewstate turned on on your GridView? This has caught me out numerous times.
<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button>

Implementing a functional link in a Repeater control

I am implementing a Repeater in my web application to display data. I want to add functional action links in a column similar to the built-in functionality in a GridView. Can anybody give me the steps required? I assume I will add a LinkButton control to each row, somehow set the OnClick event handler to point to the same method, and somehow pass in the unique identifier on the row as a parameter.
Thanks!
I'm guessing this is what you want.
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<asp:LinkButton ID="lbtn" runat="server" OnCommand="lbtn_Command"
CommandArgument='<%# DataBinder.Eval(Container.DataItem, "KeyIDColumn") %>' ></asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Then in your code behind
protected void lbtn_Command(object sender, CommandEventArgs e)
{
int id = Convert.ToInt32(e.CommandArgument);
}
Use LinkButtons. That way, you can handle the OnClick event in the code behind.
First you would set the onclick of the linkbutton in markup. You'll then want to implement the ItemDataBound event for the repeater.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
SomeObject obj = e.Item.DataItem as SomeObject; // w/e type of item you are bound to
var linkButton = e.Item.FindControl("linkButtonId") as LinkButton;
if(linkButton != null)
{
//either set a custom attribute or maybe append it on to the linkButton's ID
linkButton.Attributes["someUniqueId"] = obj.SomeID;
}
}
Then in the click event
void lb_Click(object sender, EventArgs e)
{
LinkButton lb = sender as LinkButton;
if (lb != null)
{
// obviously do some checking to ensure the attribute isn't null
// and make it the correct datatype.
DoSomething(lb.Attributes["someUniqueId"]);
}
}

Resources