We are trying here to localize our user control basically we want to be able to do something like this :
<in:Banner runat="server" ID="banners" Lang="fr" />
The way we do this is by page level and send it to master that then send it to the control:
protected void Page_Load(object sender, EventArgs e)
{
Master.Lang = "FR";
}
Then in the MasterPage.master we do something like this :
<in:Banner runat="server" ID="banners" Lang="<%= Lang %>" />
The masterpage has a public proprety named Lang.
In the control we have set a field that contains the default language and a proprety (Lang) that set the language. It seems that whatever we do, the current language is not sent from the page to the usercontrol... any help?
Not exactly like that, but you can consider the content page like a control in the master page, so its likely that the page load of the page is executing before the page load of that user control.
Regardless of the above, why not set the ui culture to the asp.net thread (probably from the global.asax), and using that from the control.
Another alternative is to have a separate class where you hold the current language, and expose a change event ... that way you can make sure to use the right language even if the load is done differently --- or there is a change language event later.
You can access it in code-behind of the MasterPage like this
public void SetLanguage(string language)
{
banners.Lang = language; //banners is an ID reference to your user control.
}
Or in your markup I think you can do it like this
<in:Banner runat="server" ID="banners" Lang='<%# Bind("Lang") %>' />
I should mention that Bind works in .Net 2.0 and up.
Related
I am working with the web application which I have only binaries. The application allows developing extension by providing internals to the derived classes.
What I would like to achieve is to add additional functionality to the existing aspx page. Because I can’t replicate and modify corresponding code I thought about developing a UserControl and modify markup of the discussed aspx page to include that control.
Until now I was successful. The control appears on the page and triggers server event handlers. It also has access to the application internal data. What I need now is to programmatically manipulate some of the original page elements from that UserControl server side.
I know that this is not the purpose of User Controls and they should not to have any knowledge about parrent page elements. However, this is as far as I know the only way to include some of the custom functionality to the existing page.
Before I asked this question I have spent a good amount of time for researching avaiable solutions.
Please, could you suggest the best possible way of referencing those elemnent from the User Control at server side?
Below is a simplified code representation of what I have done so far
The existing aspx page:
// SOME CONTENT OF THE ORGINAL PAGE
<%# Register TagPrefix="uc" TagName="MyControl" Src="~/usercontrols/MyControl.ascx" %>
// SOME CONTENT OF THE ORGINAL PAGE
<uc:MyControl ID="pnlMyControl" runat="server"></uc:MyControl>
// SOME CONTENT OF THE ORGINAL PAGE
My User Control:
public partial class MyControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
//DO SOMETHING HAVING ACCESS TO INTERNAL DATA
}
protected void lnkTest_Click(object sender, EventArgs e)
{
//DO SOMETHING HAVING ACCESS TO INTERNAL DATA
}
}
I've done something similar, though I've done it for variables rather than controls so I shall attempt to adapt it here.
I used properties to achieve this, working with:
<%# Register TagPrefix="uc" TagName="MyControl" Src="~/usercontrols/MyControl.ascx" %>
<uc:MyControl ID="pnlMyControl" runat="server" />
In the UserControl you do something like:
private string _myTextBox = new TextBox();
public string myTextBox
{
get
{
return _myTextBox;
}
set
{
_myTextBox = value;
}
}
Then in the parent page, you can set these properties; for example:
protected void Page_Load(object sender, EventArgs e)
{
pnlMyControl.myTextBox = MyParentTextBox;
}
Also, you may find this useful; you can directly fire methods on the parent from the user control using this:
this.Page.GetType().InvokeMember("MyMethodName", System.Reflection.BindingFlags.InvokeMethod, null, this.Page, new object[] { });
I hope that helps.
I am creating a custom user control that will act as a search feature. I want to easily be able to add this to multiple pages without having to modify much code.
I thought the best method to do this would be to create a simple user control that I can inject anywhere with one line of code and then have this control postback to a different URL. So wherever the search function is, it will always post back to the same page. My control looks like this:
<asp:TextBox ID="searchTextBox" runat="server" MaxLength="350"></asp:TextBox>
<asp:Button ID="submit" runat="server" Text="Search" PostBackUrl="~/myPostBackPage.aspx" />
myPostBackPage.aspx.cs looks like this, but it isn't grabbing the text.
protected void Page_Load(object sender, EventArgs e)
{
content.InnerHtml = ((TextBox)PreviousPage.FindControl("searchTextBox")).Text;
}
But it isn't pulling anything from the searchTextBox field and I get:
Object reference not set to an instance of an object.
Is there a better way to do this or how should I fix my code? Thanks!
I don't know where the TextBox is declared, if you for example use MasterPages the NamingContainer of it would be the ContentPlaceHolder of the master instead of the Page. Therefore just cast the PreviousPage property to the correct type:
YourPageType page = PreviousPage as YourPageType;
if(page != null)
{
content.InnerHtml = page.SearchText;
}
You have to provide a public property since the TextBox is protected(best-practise anyway):
public string SearchText
{
get { return searchTextBox.Text; }
}
I tested your code and PreviousPage is null. Try switch to Page.
I have an .aspx page in which I have a property. Now i create a user control and drop it on the page. Now how can i access that property in code behind of usercontrol.
The best way is to expose a public property in the UserControl and assign that property from the ASPX page:
By code:
var uc = this.myUserControl as MyCuserControlType;
uc.CustomUserControlProperty = this.MyPageProperty;
Declaratively
<uc:MyUserControlType1 runat="server= ID="myUserControl" CustomUserControlProperty="<%# this.MyPageProperty %>" />
Note: If you want to use declarative markup you would need to call this.DataBind(); in code to force the binding
Edit 1
In case you want to do the opposite (pass a value from the control to the page in response to an event) you could declare your own custom event in the user control and fire it when needed it.
Example:
User control code behind*
public event Action<string> MyCustomEvent = delegate{};
....
// somewhere in your code
this.MyCustomEvent("some vlaue to pass to the page");
Page markup
<uc:MyUserControl1 runat="server" onMyCustomEvent="handleCustomEvent" />
Page code behind
public void handleCustomEvent(string value)
{
// here on the page handle the value passed from the user control
this.myLabel.Text = value;
// which prints: "some vlaue to pass to the page"
}
If a user control needs to access something on the parent page, then maybe this user control should have included it as its own property which could be set from the parent. Ideally user controls should be independent from any parent context or other user controls on the page, otherwise they really are not something reusable. They need to be self contained and configurable throughout their the properties they are exposing.
Delegates, would those apply here? If so, how? Code examples, as I am new to this area.
Logic separation is what I am intending to implement and I think my task below would be a perfect candidate. I have read that objects should be fairly independent and not hard wired to one another.
ASPX (Page)
<uc1:Attachment ID="Attachment1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
ASPX.cs (Codebehind)
protected void Button1_Click(object sender, EventArgs e)
{
// Check the files and upload
}
ASCX (UserControl)
<MyControl:Upload ID="Upload1" runat="server"
AllowedFileExtensions=".zip,.jpg,.jpeg,.doc,.gif,.png,.txt"
MaxFileInputsCount="3"
OverwriteExistingFiles="false"
onfileexists="Upload1_FileExists"
onvalidatingfile="Upload1_ValidatingFile" />
ASCX.cs (Codebehind)
public Upload AttachmentControl
{
get { return this.Upload1; }
}
The task above is a file upload module. The control that does the upload is in a UserControl which has been dragged on to an ASPX page.
The Submit button on the ASPX page should start the file upload process.
This should be a fairly common scenario where the Page saves other information to a database and also upload files.
My instinct from past experience was to expose the Upload control in the UserControl via a public Property.
This would tie the Attachment UserControl to the the page.
How can I untie this, perhaps the use of delegates?
What information does the view need about its Attachment control? What does the Attachment control need to know about the view which contains it?
I suppose a delegate(Stream uploadContent) could let you decouple this farther, but if you're using the System.Web.Page model... the motivation to decouple things that far seems lacking.
Having the view accept a callback inverts the appropriate path of dependency in your application, doesn't it?
I don't know whether this is really possible, but I'm trying my best.
If I have a (complex) custom server control which (beside other controls) renders a TextBox on the UI. When placing the server control on a page, would it be possible to attach a RequiredField validator to that server control, such that the validator validates the Text property of that control which points to the Text property of the rendered TextBox?
Of course I could incorporate the RequiredField validator directly into the server control, but this is for other reasons not possible (we are rendering RequiredField validators automatically on the UI).
Thanks for your help.
I think one solution is to put your TextBox control inside a Panel then you add the RequiredValidator control dynamically on the Page_Load event handler.
<asp:Panel ID="Panel1" runat="server">
<MyCustomTextBox ID="TextBox1" runat="server"></MyCustomTextBox>
</asp:Panel>
<asp:Button ID="Button1" runat="server" Text="Button" />
then
protected void Page_Load(object sender, EventArgs e)
{
var validator = new RequiredFieldValidator();
validator.ControlToValidate = "TextBox1";
validator.ErrorMessage = "This field is required!";
Panel1.Controls.Add(validator);
}
I put the CustomTextBox inside the panel to assure that the validation controle place is correct when added
I got it, the 2nd time that I'm answering to my own post :) Next time I'll do a deeper research before.
For those of you that may encounter the same problem. You have to specify the ValidationProperty attribute on your server control's class. For instance if your server control exposes a property "Text" which is displayed to the user and which should also be validated, you add the following:
[ValidationProperty("Text")]
Then it should work.