I have a asp:Hyperlink with a data-attribute containing a value (a number in this case).
<asp:HyperLink ID="hypTest" href="testwebsite.com" CssClass="button-close" data-test="1" runat="server" Text="Testlink" onclick="dosomething"></asp:HyperLink>
How can I access the data attribute from this HyperLink in the codebehind when a user clicks that exact link. (there will be multiple similar links)
Also note that the onclick shown above does not work for me.
It does not access the dosomething method.
protected void dosomething()
{
//get the data-test value
}
What would be the best way to achieve this?
Thanks in advance.
If you want the server click event - use LinkButton instead of using Hyperlink.
<asp:LinkButton ID="hypTest" CssClass="button-close" data-test="1" runat="server" Text="Testlink" onclick="dosomething"></asp:LinkButton>
For the dosomething event do it like this:
protected void dosomething(object sender, EventArgs e)
{
}
For the data attribute. Take it from the Attributes Collection.
string testData = hypTest.Attributes["data-test"]
Related
I need to add a UserControl dynamicaaly to a Panel on a page. The UserControl has a Repeater with the ID of ARepeater. I load and add the UC on Page_Init. I examine the value of ARepeater in Init, Load, and PreRender events of UC but ARepeater is always null.
protected Page_Init(object sender, EventArgs e)
{
var list = (NameList)Page.LoadControl(typeof(NameList), new object[1] { (int)Type });
Panel1.Controls.Add(list);
}
The NameList.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="NameList.ascx.cs" Inherits="MyCompant.Controls.BannersList" %>
<asp:Repeater ID="ARepeater" runat="server">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
What I am doing wrong?
First of all, you do not need to be in Page_Init to work with dynamic controls. Page_Load is just fine. But in order to fill the Repeater you can create a property in the UserControl
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public Repeater _ARepeater
{
get
{
return ARepeater;
}
set
{
ARepeater = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
Then you can access it from the page using the UserControl.
protected void Page_Load(object sender, EventArgs e)
{
var list = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
list.ID = "MyUserControl";
Panel1.Controls.Add(list);
list._ARepeater.DataSource = source;
list._ARepeater.DataBind();
}
Or use FindControl
var _ARepeater = (Repeater)Panel1.FindControl("MyUserControl").FindControl("ARepeater");
_ARepeater.DataSource = dt;
_ARepeater.DataBind();
You probably won't like this answer, but the overload for Page.LoadControl that allows for specifying the control's type and adding constructor arguments doesn't bind the ascx to the code-behind, and all associated child-controls will end up being null.
In the past, I've worked around this by adding another method for setting dependencies after constructing the user control, but it's not an ideal solution.
That said you aren't doing anything wrong. Binding will work properly if you use Page.LoadControl("~/path/to/mycontrol.ascx"), but you won't have constructor injection.
I believe the issue lies with the fact that the backing class doesn't actually have a relationship with the front-end page, except through the page directive that specifies it as the code-behind class. Nothing stops multiple different front-ends using the same class as it's code-behind, so loading by Type makes it either very difficult or outright impossible to determine what the correct ascx to bind would be.
I need to implement sortable DataGrid inside User Control.
My main page code behind looks like this:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
myPlaceHolder.Controls.Add(page.LoadControl("~/myControl.ascx") as MyCtrl);
}
User Control looks like this:
<asp:DataGrid ID="myGrid" runat="server" Width="100%" AutoGenerateColumns="False"
AllowSorting="True" OnSortCommand="Grid_Sort" EnableViewState="true" >
<Columns>
<asp:BoundColumn DataField="Clmn1" SortExpression="" HeaderText="" />
<asp:BoundColumn DataField="Clmn2" SortExpression="Clmn2" HeaderText="Clmn2header" />
</Columns>
</asp:DataGrid>
So I faced following problem: when I click on automatic generated link button Clmn2header to sort data, it cause the main page to reload (not post back) and hence to create new user control. So post back never occure and sorting method Grid_Sort is never fired.
I sure that ViewState is enabled.
Help me, please. What have I done wrong?
Thank you.
EDIT
I just simplify, actually, user control initializing looks like this:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
myPlaceHolder.Controls.Add(MyCtrl.createInstance(/*some params*/));
}
And crete instance method:
public static MyCtrl createInstance(/*some params*/)
{
MyCtrl ctrl = page.LoadControl("~/myControl.ascx") as MyCtrl;
ctrl._init(/*some params*/);
return ctrl;
}
private void _init(/*some params*/)
{
/*setting controls properties with params*/
}
What is MyCtrl ? why casting as you are using loadcontrol method ? below line should be suffice to instantiate your control,
myPlaceHolder.Controls.Add(page.LoadControl("~/myControl.ascx"));
Did you put IsPostBack() checkpoint in your page_load event of the page & control, i am quite sure that when you click on column headertext link, there should not be full page postback.
if (!IsPostBack) { }
let me know if your sort command event is not hit still.
I'm having a problem with this: in my source i gave an id and runat to my <p> tag as this :
<p style="border-style:solid" id="p1" runat="server" > Hello</p>
But when i try to run this code :
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
p1.Style.Add(HtmlTextWriterStyle.BorderColor,"" + DropDownList2.SelectedItem.Text + "")
}
and also this doesn't work:
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
p1.Style.Add(HtmlTextWriterStyle.BorderColor,"Blue");
}
Please help?
Make sure your DropDownList has AutoPostback = true
To add a little: buttons such as LinkButton and Button by default will cause postbacks, but other input items like CheckBox and DropDownList do not be default. Input items that don't postback by default will have an AutoPostBack property that can be set to true to force a postback when they are changed in some way by the user.
Without setting the AutoPostBack property, ASP.NET won't be notified that the user did something, and your events (in your code-behind) will never fire.
I have spend two days trying to figure out the solution to this problem, even tried ExpertExchange and still I can't get a solution. I am a very novice programmer to ASP.Net (using C#) and I DON'T want to use a string/url post
I have a MasterPage of which has a textbox called tbSearchString. It is a simple box that a user can enter something and then it does a Postback to another page SearchResults.aspx So I also have other pages, like Default.aspx that uses the MasterPage.
I have tried nearly everything and have read nearly every post I could find on the net and no mater what the Variables are always Null.
I have use this code on the searchResults loadpage event and Every one of these variables are null, even though I enter a value in the page text box and click the button to postback to the SearchResults page, the only time it works is if I am on the searchResults page and submit.
SearchResults back end page
protected void Page_Load(object sender, EventArgs e)
{
TextBox SearchString;
TextBox SearchString2;
TextBox SearchString3;
TextBox SearchString5;
if (Page.PreviousPage != null) //This is true on every test
{
SearchString = (TextBox)Page.PreviousPage.Master.FindControl("tbSearchString");
SearchString2 = (TextBox)PreviousPage.Master.FindControl("tbSearchString");
SearchString3 = (TextBox)Master.FindControl("tbSearchString");
TextBox LoginControlx = (TextBox)PreviousPage.FindControl("Form1");
if (LoginControlx != null)
{
TextBox SearchString4 = (TextBox)LoginControlx.FindControl("tbSearchString");
}
}
MainWebsite.Master page Code
<asp:TextBox ID="tbSearchString" runat="server"></asp:TextBox>
<asp:Button ID="btnSearch1" runat="server" Text="Search" PostBackUrl="~/SearchResultRentalEquiptment.aspx" />
I don't have anything in the CS backend page
So on the Default.aspx page
nothing special Just the Masterpage and some text content, I enter some text in the textbox goes to the SearchResults page and I can not get the darn value from the Textbox control from the Default or any other page.
What say you wise ones?
how do you redirect your form to search result form? if you are using Response.redirect, the value under Page.PreviousPage.Master.FindControl will be null . Try to use Server.Transfer to see if it works.
Here's one way:
Assuming this is your Master Page code:
<asp:TextBox ID="searchbox" runat="server" /><br />
<asp:Button ID="sendSearch" runat="server" PostBackUrl="~/Results.aspx" Text="Search" />
At the end of the day, it's all about HTTP POST, so in the target page Results.aspx PageLoad:
protected void Page_Load(object sender, EventArgs e)
{
string _foo = Request.Form[this.Master.FindControl("searchbox").UniqueID];
}
Hth....
Check out Session. I use it all the time when I need to get data from one page to another. I'm not currently able to write out a full example for you, but off the top of my head the following should work:
//page1.aspx:
protected void btnSubmit_Click(object sender, EventArgs e)
{
string greetingString = "Hello";
Session["MyValue"] = greetingString;
Response.Redirect("page2.aspx");
}
//page2.aspx:
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(Session["MyValue"].ToString()); //prints "Hello"
}
Let's say a control X has a template called RowTemplate.
So X's markup would be like:
<foo:X>
<RowTemplate>
<foo:Y>...</foo:Y>
</RowTemplate>
</foo:X>
My question is: How can the Y control be sensitive to the data context? I know I can use template inline tags to get access to the data context: <%# Eval("Id") %>, but I cannot pass this information to Y because template inline tags are not allowed in server controls.
So I don't know how I could use the Object's Id (Eval("Id")) in Y.
By adding a handler to the ItemDataBound event (or some other similar event on your foo:X control), you can access controls in your row template. My example code is from a DataList, so your event handlers will probably be different.
In the code behind - wire up the event handler:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
foo.ItemDataBound += new DataListItemEventHandler(foo_ItemDataBound);
}
Then in the event handler, access the controls in your row. Your data might not be a DataRow, so change that as needed.
void foo_ItemDataBound(object sender, DataListItemEventArgs e)
{
Control fooY = (e.Item.FindControl("foo:Y") as Control); //Replace foo:Y with the ID for foo:Y
DataRow data = e.Item.DataItem as DataRow;
fooY.SomeProperty = data["id"];
}