How to Access Controls from UserControls in ASPX page?
For example:
I want to access gridview which is in usercontrol on ASPX page.
Please help me.
Try this :
GridView GridView1 = (GridView)WebUserControl1.FindControl("GridView1");
Where WebUserControl1 is ID of use control on .aspx page.
Hope this helps..
The best way is to provide properties in your UserControl that you can access.
For example:
public GridView UserGrid
{
get
{
return GridView1;
}
}
But the question is why you need this.
Rule of thumb: Only expose as few as possible. On that way your code will be most robust and readable. So it would e.g. better to expose it's DataSource rather than the complete GridView.
On the other hand, if you want your page to react on events in your UserControl, it should provide custom events(e.g. UserDeleted) that your page then can handle.
Page-UserControl-Commmunication
Because the controls now nothing about eachother at the same level, you have to use the parent page to get it. Try this logic:
Create a property referring to your parent page (the page your control usually is in (might be different because of layering of controls)
Create a property on your page referring to the usercontrol the grid is in, or link to that grid directly.
page.aspx
public UserControl UserGridControl
{
get;
set;
}
userControl.ascx
public Page ParentPage
{
get;
set;
}
Example call:
Instantiate the properties first. After that, use the following statement to access anything from that control (as an example I used Foo() here, to use as a dummy method, but it seems it was unclear to someone):
otherControl.ascx:
this.ParentPage.UserGridControl.Foo();
EDIT: Want to have a direct code example to be able do it from the page only? See Tim Schmelters answer. If you need a way to call the grid from another user control as well. Use mine.
Related
I have a UserControl (ascx) that, depending on the user's credentials, will load another UserControl (ascx). Currently the control to be loaded, contains a special navigation menu.
I am using this code:
UserControl jmNav =
(UserControl)Page.LoadControl("~/controls/client/jmNavigation.ascx");
Then, after some more code, I'm telling it to load, like this:
SBarTopWelcome.Controls.Add(jmNav);
The problem is, that I'm getting an "object reference not set to instance of an object" error.
Yes, the path is correct - as I tried it like this, as well (in all variations):
UserControl jmNav = (UserControl)Page.LoadControl("/client/jmNavigation.ascx");
This one (and its variants) tells me it doesn't exist.
So! Any thoughts?
One helpful solution is to add <%# Register %> to your parent control. Yes, I know it's in your parent page, but it should also be in your control.
If you do this, you should be able to Strongly-Type your control. For example, a control with a class name of MyControl would be:
MyControl controlVar = (MyControl)this.LoadControl("MyControl.aspx");
If you are able to get the stronly-defined variable, you should have no problems.
Inside SideBar.ascx add a place holder named SideBarTopWelcomePlaceHolder.
<asp:PlaceHolder ID="SideBarTopWelcomePlaceHolder" runat="server"/>
Then load jmNavigation UserControl to SideBarTopWelcomePlaceHolder like this.
Control jmNav =
Control Page.LoadControl("~/controls/client/jmNavigation.ascx");
SideBarTopWelcomePlaceHolder.Add(jmNav);
HA! I'm such a DORK! I was declaring the "SideBarWelcome" within a control like this:
public Control sideBarTopWelcome
{
get { return Page.FindControl("SideBarTopWelcome"); }
}
When I should have done it like this:
public Control sideBarTopWelcome
{
get { return FindControl("SideBarTopWelcome"); }
}
Without Page. Thank you anyway, guys. I appreciate it.
Is it possible to acces a control thats located in a content page (withing a content place holder, a multiview control to be more exactp) from the master page?
The situation is, i have a menu with buttons thats located in the master page.
Now in my content page i have 1 content place holder.
In which a multiview with several views is located.
If i press a button in the menu (MasterPage) then it should open the proper view (with its controls) displayed in the content place holder area.
I have set the ActieveViewIndex=0 but i am getting all sorts of wierd behavour.
I have to do something with the ActiveViewIndex++ somewhere but nothing seems to work.
edit::
string a = Request.Querystring["one"]
string b = Request.QueryString["two"]
if ( a == "addOne") // where addone is a redirection to the content page from the master page button
{
mvMultieView.SetActiveView(vView1);
}
else
if ( b == "addTwo")
{
mvMultieView.SetActiveView(vView2);
}
Any suggestions?
Kind Regards.
You can easily do that using find control
View myView = (View)this.Master.FindControl("PlaceHolderFullMain").FindControl("PlaceHolderMain").FindControl("Mymultiview")
The way my team and I accomplished this task (and I don't know that it's the best method, but it was effective) was to use query strings (as you had in your previous question it looks like). We established a standard QS variable called iView that would determine the name of the view in question (not necessarily the control name itself, but some keyword that the content control would respond to). Since all of our pages/controls have a page base class they inherit from, we put a method in the base class (in our case it was at the page level, but in yours a control level might work) that was responsible for getting the requested view. In the control we would have a mechanism (switch perhaps) that would set the activeView. In some cases we just used the actual ID of the control (since it was a mystery to be obfuscated) and avoided the switch altogether.
http://www.mydomain.com/mypage.com?iView=mySecondView
partial class MyControl : System.Web.UI.WebControl
{
// blah blah control stuff
public string getRequestedView()
{
return (Request.QueryString["iView"]) ? Request.QueryString["iView"] : String.Empty;
}
}
...
protected void Page_Load(object sender, EventArgs e)
{
View myView = myMultiView.FindControl(this.getRequestedView());
if(myView != null)
this.MyView.SetActiveView(myView);
}
have you done this change in the Master page or content page?
because i also got the same problem.
I have link buttons in my master page which i need to activate view controls in content page.
the content page is not the currently loaded page.
will this method help for my solution?
I am using a user control that I created (just a .cs file not an .ascx file), that does some magic and depending on a value generated by the control, I need it to do something on the parent page that is 'hosting' the control. It needs to call a method under certain circumstances (method is on the parent control).
the control is placed on the parent page like so:
<customtag:MyControl ID="something" runat="server" />
I'm dynamically creating buttons etc on the control itself but when a button is clicked, let's say for example that there's a text box on the control and if the value of the textbox is "bob" it needs to call a method on the page that's housing the control...how can I accomplish this?
You could do what casperOne suggested, but I wouldn't advise it. This is tightly coupling your user control to your parent page, which kind of defeats the purpose of a user control.
Personally, I'd add an event to the user control (say, ButtonClicked) that the parent page can handle. In the event handler in your parent, deal with the event however you see fit. This way you can plug the user control into a different page at a later date and not have to worry about logic in the user control that requires a specific kind of parent page.
You should be able to get the Page hosting the control through the Parent property. However, that's going to be returned to you as a Control. You have to cast it to the type of your page in order to access any methods on the page which you have defined.
I think that casperOne is on the right track, but you need to go a step further. I'm giong to make the assumption that this user control will be used on more then on page. (I normally write VB.Net, sorry if my C# is malformed)
Make a base page class (you can store it in your App_Code directory or in a project):
public class PageToInheritFrom : System.Web.UI.Page {
public void SpecialFunction() {
}
}
Now make sure that all of your pages inherit from this page in your code behind file:
public partial class _Default : PageToInheritFrom {
}
Now in your user control you know what the page type is and can call
((PageToInheritFrom)this.Page).SpecialFunction();
I am developing a web application where I would like to perform a set of validations on a certain field (an account name in the specific case).
I need to check that the value is not empty, matches a certain pattern and is not already used.
I tried to create a UserControl that aggregates a RequiredFieldValidator, a RegexValidator and a CustomValidator, then I created a ControlToValidate property like this:
public partial class AccountNameValidator : System.Web.UI.UserControl {
public string ControlToValidate {
get { return ViewState["ControlToValidate"] as string; }
set {
ViewState["ControlToValidate"] = value;
AccountNameRequiredFieldValidator.ControlToValidate = value;
AccountNameRegexValidator.ControlToValidate = value;
AccountNameUniqueValidator.ControlToValidate = value;
}
}
}
However, if I insert the control on a page and set ControlToValidate to some control ID, when the page loads I get an error that says Unable to find control id 'AccountName' referenced by the 'ControlToValidate' property of 'AccountNameRequiredFieldValidator', which makes me think that the controls inside my UserControl cannot resolve correctly the controls in the parent page.
So, I have two questions:
1) Is it possible to have validator controls inside a UserControl validate a control in the parent page?
2) Is it correct and good practice to "aggregate" multiple validator controls in a UserControl? If not, what is the standard way to proceed?
Addressing your second question first- I don't think it's a good idea to "aggregate" validators together this way unless you include the controls you're validating in the user control. Too much work for not enough payoff.
You could fix this problem by exposing properties on your AggregatedValidator to set the names of the controls to validate, and pass in the ClientID of those controls you want validated.
I believe ASP.NET expects the ControlToValidate ID to be in the same naming container. You can probably override the validation method and use Parent.FindControl.
EDIT: This might be a good place to use a CompositeControl rather than a UserControl. They are designed for just this kind of aggregation. But you might have a similar NamingContainer issue.
Context: ASP.NET 3.5 / C#
Hi,
I created a user control
public partial class MyControl : UserControl
{
// EDIT: example first used "UniqueId" as property name, which was wrong.
public Guid MyId { get; set; }
// ...
}
and this example usage
<uc1:MyControl
ID="myControl"
MyId="443CBF34-F75F-11DD-BE2F-68C555D89123"
runat="server" />
Steps:
Add this control to a web form (aspx)
Expected result:
the HTML for the user control is added, a unique value (corresponding to Guid.NewGuid()) for MyId is set in the ASPX HTML at design-time as the MyId attribute value.
Actual result:
the HTML for the user control is added, a unique value for MyId is not set in the HTML at design time for the MyId Attribute value.
If this is not possible:
Workaround 1: Would it be possible to achieve this using a server control? How?
Workaround 2: is it possible to achieve this using a UserControl design-mode task?
Clarification:
persisting the property value is not an issue, since it never changes for a control intance and is automatically set by ASP.NET through the control declaration in the aspx page.
the MyId attribute does not need to be rendered at runtime.
Gr B!
Custom Design-time Control Features in Visual Studio .NET
You have a couple problems here, but first I will answer your questions about the workarounds.
No you are already using a server control.
No design-mode is to just make the lives of the developer easy, it doesn't effect anything else
You have two problems here. There is already a property called UniqueID I don't know if you were trying to overload that, but the question wasn't clear. The second problem is that your UniqueID essentially not getting stored anywhere. Try the following code:
public Guid UniqueId {
get { return (Guid)ViewState["MyUserControlUniqueId"]; }
set { ViewState["MyUserControlUniqueId"] = value; }
}
That will store the GUID in the ViewState so that you can retrieve it on post backs.
Update: Given your comment you need to override/use this method to add attributes to the rendered content.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol.addattributestorender.aspx
If I understand your question correctly, you are exposing a property on your user control called MyId. This allows you to set the property wherever you put that control.
What you also want, is for the rendered HTML to also include this attribute and value.
If that's the case, the property MyId is not passed through to the HTML, it's only because the user control has MyId as a property that it's visible in the designer.
In your user control you will have defined the markup that gets rendered.
So for example if you have:
<asp:Panel runat="Server" Id="myControlDiv">Some other content</asp:Panel>
You can then in your controls prerender event (or wherever else you choose) put
myControlDiv.Attributes.Add("MyId", SomeGuid.ToString())
Which will then get output in the HTML as
<div id="generatedID" MyID="443CBF34-F75F-11DD-BE2F-68C555D89123">Some other content</div>
So you just want a unique ID generated that you only ever use in design time?
Why not override Object.GetHasCode();
And then exposure this as a property?