I have a template property in my control declared as follows:
<TemplateContainer(GetType(GenericTemplateContainer)),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateInstance(TemplateInstance.Single)>
Property CustomTemplate As ITemplate
In my control's Init event I have the following:
If Me.CustomTemplate IsNot Nothing Then
Dim TemplateContainer As New GenericTemplateContainer
Me.CustomTemplate.InstantiateIn(TemplateContainer)
PlaceHolder.Controls.Add(TemplateContainer)
End If
This allows me to place controls in markup inside my template, but on a post back the controls inside the template are not holding their ViewState.
I have tried adding PersistChildren(True) attribute to CustomTemplate property but I cannot because it's not valid.
Are you putting the values into ViewState? From what I understand, you need to do that. Either that, or re-bind with the data on every postback.
Here's what I like to do inside User Controls. I apologize for this being C# and not VB, but I don't know VB:
public string Text {
get { return (string)ViewState["Text"]; }
set { ViewState["Text"] = value; }
}
Reference: https://weblogs.asp.net/infinitiesloop/Truly-Understanding-Viewstate
Related
I have this following property in my custom user control:
public string selectedtab
{
get
{
if (ViewState["AdminCurrentNavID"] != null)
{
return ViewState["AdminCurrentNavID"].ToString();
}
else {
isfirstload = true;
return null;
}
}
set { ViewState["AdminCurrentNavID"] = value; }
}
I am setting the value of it on my Page_Load() in ascx control. What i need to do is that after setting the value of this property I need to access it from masterpage.cs in code behind. you can see how currently I am trying to do in below code, but the issue is that I am not able to get the value i thing it is because the masterpage's Page_Load() rendering before the ascx control so I thats why I am getting null value, please help, thanks.
masterpage.cs:
usercontrols.mainmenu adminmenu = (usercontrols.mainmenu)LoadControl("~/mymenupath.ascx");
lbmsg.Text = adminmenu.selectedtab;
When you call LoadControl in your master page, you are actually creating a new instance of your user control, not accessing the one you have somewhere in your site.
When you declare the User Control in your page you should have given it an id. You could access the property with something like ((usercontrols.mainmenu)MyUserControlId).selectedtab
I found the solution by using Delegate, you can see in the link below.
http://webdeveloperpost.com/Articles/Return-value-from-user-control-in-ASP-NET-and-C-Sharp.aspx
I have a custom user control that I made called OrderForm.ascx. I also have an .aspx file that utilizes the OrderForm control.
I want to access a control on the .aspx file from the OrderForm control. Is there a way to do this?
You could use the FindControl method in the user control like this:
Label label = Page.FindControl("Label1") as Label;
if (label != null)
string labelText = label.Text;
As a note on the above, depending on where the Label is in the page, you may need to use recursion to find the Label.
You could also create a property on the page that returns the text of the Label:
public string LabelText
{
get { return Label1.Text; }
}
To access the property from the user control, here are two options:
Option #1
string labelText = ((PageName)Page).LabelText;
Option #2
string labelText = Page.GetType().GetProperty("LabelText").GetValue(Page, null).ToString();
If you have two user controls, ControlA and ControlB, and they are both registered on the same page you can easily access one from the other. Simply create a public property that you want to have access to in ControlB such as:
Public ReadOnly Property ControlB_DDL() As DropDownList
Get
Return Me.ddlItems
End Get
End Property
And then you can reference that property in ControlA after finding that control:
ControlB ctrlB = (ControlB)Page.FindControl("cB");
DropDownList ddl = ctrlB.ControlB_DDL;
Refer here for more info: http://www.dotnetcurry.com/ShowArticle.aspx?ID=155
To access the controls of .ascx in .aspx.
HiddenField selectedEmailsId = performanceReportCtrl.FindControl("CONTROLID") as HiddenField;
And to access controls of aspx in ascx.
HiddenField selectedEmailsId = Page.FindControl("CONTROLID") as HiddenField;
I am loading a control to a page dynamically with LoadControl("src to file").
In the usercontrol i have a validator and some other controls that i would like to access from my page. I canät get it to work, null pointer exception.
Scenario is like this. I have a Edit.aspx page which loads the EditTemplate.ascx usercontroll. I would like to get information or find the controls in the EditTemplate from the Edit.aspx site.
I have tried exposing the controls and validators as properties but how do i access them from my Edit.aspx?
Example code:
Edit.aspx, the control is later added into a
Control control = LoadControl("src to ascx");
TemplatePlaceHolder.Controls.Add(control);
EditTemplate.ascx
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="CompanyImageFile" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
CodeBehind
public partial class EditTemplate : System.Web.UI.UserControl, IEditTemplate {
public RequiredFieldValidator Validator {
get { return this.RequiredFieldValidator1; }
set { this.RequiredFieldValidator1 = value; }
}
From the Edit.aspx site i would like to check the validators isValid property. Isvalid is set in a Save method.
The save button that saves the template is located in edit.aspx, so the post in done from that page.
So the question is how to get a hold of the property from the usercontrol in the edit.aspx page, where and how should this be done?
Thanks again.
Easiest way is to have the user control define properties like:
public IValidator SomeValidator {
get { return this.cuvValidator; }
set { this.cuvValidator = value; }
}
public string Text {
get { return this.txtText.Text; }
set { this.txtText.Text = value; }
}
Which your edit page can use.
HTH.
You can always use recursive approach. Check the solution on Steve Smith's blog:
Recursive-FindControl.
As mentioned in previous answers, I would expose any validators you must access from the parent ASPX page as properties in the user control.
public RequiredFieldValidator ValidatorToCheck
{
get { return this.rfvMyField; }
}
Then, you can dynamically add your user control to some placeholder (being sure to assign an ID to the user control).
// In my example, this is occurring in the Page_Load event
Control control = LoadControl("~/Controls/EditTemplate.ascx");
control.ID = "ucEditTemplate";
pnlControlHolder.Controls.Add(control); // the placeholder in my example is a panel
When you want to access the IsValid property on the given validator (presumably in your save action) you can do so as follows (being sure to cast the control to the appropriate type and using the ID you originally assigned to the user control):
EditTemplate control = (EditTemplate)pnlControlHolder.FindControl("ucEditTemplate");
if (control.ValidatorToCheck.IsValid)
{
// Some action
}
For example, I have a user control(ascx) with a label inside,
I will use the the user control in my aspx page.
How can I pass a string value to the ascx page so that it can be display in the label of ascx page at the beginning?
Add this...
public string Whatever
{
get { return label.Text; }
set { label.Text = value; }
}
to your ascx control. Then from the page you are putting it in you can just set the text like... usercontrol.Whatever = "text to display";
or you can use the Whatever as a property on the aspx side of the page.
You can expose whatever controls you want access to in your user control by creating property for them.
In the past when I have had user controls that required certain data for setup I would create an Initialize method which would take in and setup whatever was needed.
Ok time to show my complete lack of knowladge for all things web forms but here goes. I am extending the Panel control and OnPreRender sticking some additional controls inside of it (lets just say 1 textbox for simplicity). From here I am just letting the Panels Render method do its thing.
The issue I am having is that obviously every time this control is rerendered it is just sticks that same TextBox in the panel again with the value I am coding in the OnPreRender method. Now I dont actually want to repopulate the panel every time,
I want to stick the textbox contorl in there on first load and have them reloaded from the control/viewstate caches. In this case with my example of just sticking a single textbox in the panel, if the value of the textbox changes and a postback occurs I want that value to to remain the changed value.
Really basic webforms stuff I know, but I have never had to create custom controls in my time. ANy help appreciated.
Chris.
You need to (re)create the child control (the textbox) in OnInit - so that it's there when LoadViewState and ProcessPostBackData is called.
See the server control lifecycle for more info.
Dynamic controls in ASP.NET are tricky, especially if you are new to webforms and the page lifecycle. If you can avoid dynamic controls, do so. Use controlName.Visible=false, and other tricks instead.
If you must then read this article. Rule of thumb,add controls early in the page life cycle, reference them later in the page lifecycle. PreRender is almost the very end, an uncommon place to be adding and using controls.
Not sure if this applies to all versions of .Net, (I think 2.0 or later) but there is a method called CreateChildControls that isn't really a part of the lifecycle exactly, it's basically called anytime the EnsureChildControls method is called. By default it is called before PreRender if it's not a postback. So basically your code would look like this:
public class SomeControl : WebControl, INamingContainer
{
private TextBox someTextBox;
protected override void CreateChildControls()
{
base.CreateChildControls();
someTextBox= new TextBox();
someTextBox.ID = "tbxMain";
Controls.Add(textboxToCheck);
}
}
Now the part to not is that unless you call EnsureChildControls, you can't be 100% sure that the controls exist before the Public Properties on your control are filled by the ViewState load. What does this mean? Well take the code from before and add a property for the CssClass:
public class SomeControl : WebControl, INamingContainer
{
private TextBox someTextBox;
protected override void CreateChildControls()
{
base.CreateChildControls();
someTextBox= new TextBox();
someTextBox.ID = "tbxMain";
Controls.Add(textboxToCheck);
}
public String CssClass { get; set; }
}
In CreateChildControls you won't want this:
someTextBox.CssClass = CssClass;
Since there is no way to be sure the control exists yet. There's a couple ways you can handle this:
public String CssClass
{
get
{
EnsureChildControls();
return someTextbox.CssClass;
}
set
{
EnsureChildControls();
someTextbox.CssClass = value;
}
In this example I am calling EnsureChildControls (Assuming you are setting the CssValue on the textbox in the CreateChildControls method) and setting or getting from the textbox.
Another way is putting anything that depends on the control's public properties in the OnPreRender method:
protected override void OnPreRender(EventArgs e)
{
someTextbox.CssClass = CssClass;
}
Thus avoiding the mess of worrying about the property being filled already during the ViewState load.
One Note:
The use of INamingContainer can be important. Basically all that does is makes sure the controls on the parent control have an id that is unique on the page by applying the parent's name (And maybe more) to the id. Basically if the parent ID is Parent and the child control ID is Child the ID might show up as Parent_Child. This will solve problems with ViewState not populating the properties correctly or not at all.
Inside your code you will need to manage the restore of viewstate information should you need the services of viewstate.
A good example here is this View State example by Microsoft. There are a few other items referenced in the code sample, but it should get you along the right path.