Localization inside an ascx user control - c#

----------------OLD CODE ----------------------------------------------
I have create a user control, which is a Main Menu, that has to be localized. So I have created 3 resource files inside the App_LocalResources, and I have a dropdown to change the languages selected.
The Main Menu looks like this :-
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MainMenu.ascx.cs" Inherits="GGX4._2.MainMenu" %>
<div>
<asp:DropDownList ID="ddlLangs" runat="server"
onselectedindexchanged="ddlLangs_SelectedIndexChanged" AutoPostBack="True" meta:resourcekey="ddlLangsResource1">
<asp:ListItem Text="English" Value="en-US" meta:resourcekey="ListItemResource1"></asp:ListItem>
<asp:ListItem Text="German" Value="de-DE" meta:resourcekey="ListItemResource2"></asp:ListItem>
<asp:ListItem Text="Spanish" Value="es-ES" meta:resourcekey="ListItemResource3"></asp:ListItem>
</asp:DropDownList>
</div>
<div>
<table>
<tr>
<td width="100%" nowrap height="16">
<img border="0" src="Images/GREENSQUARE.gif" width="16" height="16"><b><font size="2" face="Arial">
<asp:HyperLink ID="hypIntroduction" runat="server" NavigateUrl="Overview.htm"
meta:resourcekey="hypIntroductionResource1" >[hypIntroduction]</asp:HyperLink>
</tr>
<tr>
<td width="100%" nowrap height="16">
<img border="0" src="Images/GREENSQUARE.gif" width="16" height="16"><b><font size="2" face="Arial">
<asp:HyperLink ID="hypGlobalGradingMethodology" runat="server" NavigateUrl="GGMethodology.htm"
meta:resourcekey="hypGlobalGradingMethodologyResource1" >[hypGlobalGradingMethodology]</asp:HyperLink>
</td>
</tr>
<tr>
<td width="100%" nowrap height="16">
<img border="0" src="Images/Redsquare.gif" width="16" height="16"><b><font size="2" face="Arial">
<asp:HyperLink ID="hypDeterminingBusiness" runat="server"
NavigateUrl="ScopematrixGeneral.htm"
meta:resourcekey="hypDeterminingBusinessResource1">[hypDeterminingBusiness]</asp:HyperLink>
</td>
</tr>
<tr>
<td width="100%" nowrap height="16"><font size="2" face="Arial">
<img border="0" src="Images/BLUEBULLET.gif" width="16" height="16">
<asp:HyperLink ID="hypMethodology" runat="server"
NavigateUrl="methodology.htm"
meta:resourcekey="hypMethodologyResource1">[hypMethodology]</asp:HyperLink>
</font>
</td>
</tr>
</table>
</div>
and in the code behind I have the following :-
string defaultLanguage = Thread.CurrentThread.CurrentUICulture.ToString();
protected void Page_Load(object sender, EventArgs e)
{
this.InitializeCulture();
}
protected void InitializeCulture()
{
if (String.IsNullOrEmpty(CurrentCulture))
{
CurrentCulture = defaultLanguage;
}
if (!String.IsNullOrEmpty(CurrentCulture))
{
try
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(CurrentCulture);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
}
catch
{
throw;
}
}
}
public String CurrentCulture
{
get
{
if (null != Session["PreferedCulture"])
return Session["PreferedCulture"].ToString();
else
return "en-US";
}
set
{
Session["PreferedCulture"] = value;
}
}
protected void ddlLangs_SelectedIndexChanged(object sender, EventArgs e)
{
Session["PreferedCulture"] = ddlLangs.SelectedValue;
InitializeCulture();
}
However when I do the change in the dropdownlist, the Culture reamins the same. Normally when applied to a System.Web.UI.Page, I would override the InitializeCulture(), however I cannot find a way to do it in the ascx.
How can I achieve that?
Thanks for your help and time
-------------NEW CODE-----------------------------------------------
I have decided to make things simpler, and I have managed to achieve what I want, however with a page refresh which I do not like at all and wish to make without.
So basically I have created a simple example that is working now :-
The Site.Master just has the drop-down as the extra code :-
<div>
<asp:DropDownList ID="ddlLangs" runat="server" onselectedindexchanged="ddlLangs_SelectedIndexChanged" AutoPostBack="True"
meta:resourcekey="ddlLangsResource1">
<asp:ListItem Text="English" Value="en-US"
meta:resourcekey="ListItemResource1" ></asp:ListItem>
<asp:ListItem Text="German" Value="fr-FR" meta:resourcekey="ListItemResource2" ></asp:ListItem>
<asp:ListItem Text="Spanish" Value="it-IT"
meta:resourcekey="ListItemResource3" ></asp:ListItem>
</asp:DropDownList>
</div>
and the code behind looks like this:-
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["PreferredCulture"]!= null)
ddlLangs.SelectedValue = Session["PreferredCulture"].ToString();
}
}
protected void ddlLangs_SelectedIndexChanged(object sender, EventArgs e)
{
Session["PreferredCulture"] = ddlLangs.SelectedValue;
Server.Transfer(Request.Path);
}
The Default.aspx has the MainMenu UC, and a sample label, however it inheris from the BasePage :-
<asp:Content ID="MenuContent" runat="server" ContentPlaceHolderID="MainMenuContent">
<uc:MainMenu runat="server" ID="ucMainMenu" />
Welcome to ASP.NET!
</asp:Content>
And the BasePage has the code to Initialize the Culture
I wish to get rid of the Server.Transfer(Request.Path), and avoid refreshing the page, however I have not found out a method yet.
Any help/ideas will be very much appreciated!
Thanks

InitializeCulture() method execute earlier in Page life cycle, hence the culture you are setting in this method is old one..not the one user has selected..so you have to request a page again to set the culture user has selected.that's what you doing by Server.Transfer(Request.Path)..
if you want to avoid 'Server.transfer'.. you need get the new value of culture during InitializeCulture() method execution and assign that new value. here is the link this shows you how to retrieve new value during InitializeCulture() method execution.
Hope this helps..

This is quite an old post, but since localization can be a bit tricky, I have some tips.
For each page, you need to override web.ui.page with the code below. So what I do is create a new class that inherits from web.ui.page and have the aspx pages inherit from that new class: In this case PortalPage.
public class PortalPage:System.Web.UI.Page
{
protected override void InitializeCulture()
{
string _language = (string)Session["Language"];
if (_language == null)
{
_language = ConfigurationManager.AppSettings["DefaultLanguage"];
Session["Language"] = _language;
}
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(_language);
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(_language);
base.InitializeCulture();
}
}
Next, instead of inheriting your webpages from System.Web.UI.Page inherit from your new class. In this example: PortalPage
public partial class pages_Databases : PortalPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
Then put all resource files (.resx) in the appropriate subfolders (App_LocalResources) and make sure, your resx file names match your webcontrols.
Finally: Recompile! or rebuild! Your webcontrols will not be refreshed / show results without.

Related

ASP.NET - ImageButton within a Repeater refuses to raise a click event

No matter what combination I try, the button (ibtnDeleteDiaryEntry) simply will not raise an event although it does seem to do postback as it should. ViewState is turned on by default, read elsewhere that it is sometimes problematic. Also, I've used the Repeater's OnItemCommand property as required. Any kind of help is appreciated.
EDIT: It seems that the problem is somehow connected to the jQuery UI's Accordion Widget. The repeater is located within a div that is used to initialize the accordion. If I remove the div tags surrounding the repeater, the OnItemCommand event gets called. Very weird.
Markup:
<asp:Repeater ID="repAccordion" OnItemCommand="repAccordion_OnItemCommand" runat="server">
<ItemTemplate>
<h3> <%# "Date: " + Eval("date", "{0:d}") %>
<span class="deleteButtonContainer">
<asp:ImageButton ID="ibtnDeleteDiaryEntry" CommandArgument='<%# Eval("diary_entry_id") %>' CommandName="Delete" AlternateText="ibtnDeleteDiaryEntry" ImageUrl="images/remove_item.png" runat="server" />
</span>
</h3>
<div>
<table>
<tr>
<td>
<asp:Label ID="lblText" runat="server" ForeColor="#AA0114" Text="Text:"></asp:Label>
</td>
</tr>
<tr>
<td>
<%# Eval("text") %>
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
_db = new PersonalOrganizerDBEntities();
_diary_entryService = new Diary_EntryService();
_userService = new UserService();
if (!IsPostBack)
{
LoadItems();
}
}
public void LoadItems()
{
long currentUserId = (long) Session["userId"];
User currentUser = _userService.GetById(currentUserId);
Diary_Entry[] diaryEntriesArray =
_diary_entryService.GetAll().Where(current => current.diary_id == currentUser.user_id).ToArray();
if (diaryEntriesArray.Length == 0)
{
noItems.Text = "You currently have no diary entries.";
noItems.Visible = true;
}
else
{
noItems.Visible = false;
}
repAccordion.DataSource = diaryEntriesArray;
repAccordion.DataBind();
}
protected void repAccordion_OnItemCommand(object sender, RepeaterCommandEventArgs e)
{
Response.Write("test");
}
If it doesn't work I would recommend removing OnItemCommand from repeater and adding OnClick event for ImageButton instead. In OnClick event in code behind you can cast 'sender' to ImageButton and read CommandArgument value to get diary_entry_id.

How to pass variable from textbox to code behind back to same page

I have a webs form page and I have a text box which once clicked passes a variable to the code behind and then back into another element of that page and I cannot get it to work.
This is the closest I have got.
<asp:Panel ID="Search" runat="server" Visible="true">
<tr>
<td>
<asp:Label ID="lblSearch" runat="server" Text="Search"></asp:Label>
</td>
<td>
<asp:TextBox ID="search" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="valSearch" runat="server"
ControlToValidate="movieSearch" Text="Please enter text" />
</td>
<td>
<asp:Button ID="btnSubmit" runat="server" Text="Save"
OnClick="btnSubmit_Click" />
</td>
</tr>
</table>
</asp:Panel>
<asp:Panel ID="pnlSearchResult" runat="server" Visible="false">
<script>
var search = '<%=Server.UrlDecode(Request.QueryString["Data"]) %>';
</script>
</asp:Panel>
And the code behind:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (IsValid)
{
pnlSearch.Visible = false;
pnlSearchResult.Visible = true;
Response.Redirect("search.aspx?Data=" + Server.UrlEncode(search.Text));
}
}
Also this does not change the visibility of the two panels for some reason.
I would appreciate any guidance I am very new to asp and c#.
The panel's visibility is not changing because you're forcing a new GET request to the page with this: -
Response.Redirect("search.aspx?Data=" + Server.UrlEncode(search.Text));
(I'm assuming your page is called 'search.aspx')
There's no need to do this. Remove this line.
Secondly, I see you want to force the textbox's Text value into a Javascript variable. Replace this
var search = '<%=Server.UrlDecode(Request.QueryString["Data"]) %>';
with this
var search = '<%= search.Text %>';
Write below code on page event.
Another more important point is you first panel Id is "Search" not "pnlSearch" on aspx page so please correct it
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["Data"] != null)
{
Search.Visible = false;
pnlSearchResult.Visible = true;
}
}
I recommend solution without using Response.Redirect.
Code Behind Submit Button click:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (IsValid)
{
pnlSearch.Visible = false;
pnlSearchResult.Visible = true;
}
}
In Markup:
<asp:Panel ID="pnlSearchResult" runat="server" Visible="false">
<script>
var searchTxt = document.getElementById('search');
if(searchTxt.value != null && searchTxt.value != ''){
//do your stuff
}
</script>

FindControl can't find a control

I have a problem with FindControl function. The problem is as follow:
aspx:
<asp:Content ID="MainContent" ContentPlaceHolderID="MainContent" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</ajaxToolkit:ToolkitScriptManager>
<table class="inputTable">
<tr><td>
<asp:CheckBox ID="Extern" AutoPostBack="True" OnCheckedChanged="OnCheckedChangedMethod" runat="server" />
</td><td>Externes Unternehmen</td></tr>
<tr>
<td>
<asp:TextBox ID="Firmierung" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="Firmierung" Display="Dynamic"
ErrorMessage="RequiredFieldValidator"
Text="Bitte geben Sie die Firmierung ein."></asp:RequiredFieldValidator>
</td>
</tr>
</table>
aspx.cs:
protected void OnCheckedChangedMethod(object sender, EventArgs e)
{
if (Extern.Checked)
{
Control ctr = FindControl("RequiredFieldValidator1");
if (ctr != null)
{
ctr.Visible = false;
}
}
else
{
}
}
But FindControl didn't work, it couldn't find that control. Was I wrong at any point?
Thanks in advance.
ASP.NET creates a field for you, as it is located inside a Content: this.RequiredFieldValidator1 in your page.
The FindControl way would be like this (find it in the master page's content panel):
Control ctr = Master.FindControl("MainContent")
.FindControl("RequiredFieldValidator1");
Based on your limited source, you should be able to simplify your code behind method to:
protected void OnCheckedChangedMethod(object sender, EventArgs e)
{
this.RequiredFieldValidator1.Visible = this.Extern.Checked;
}
There should be no need for the use of FindControl().
When you type "this.", if you don't see RequiredFieldValidator1 appear in your intellisense, and assuming you are using ASP.NET 2.0 or greater, check your VS.NET warnings to see if your .aspx has a warning message with an associated "Generation of designer file failed". If so, you must correct the warning.

Defining the click event for a Login control integrated button

Gooday. I have a login control, with an integrated user textbox and login button. I did this little test to see how it works, and surprisingly, after doing this:
protected void LoginButton_Click(object sender, EventArgs e)
{
TextBox userTextBox = (TextBox)Login1.FindControl("UserName");
userTextBox.Text = "You pressed the button";
}
the userTextBox doesn't change to "You pressed the button". Why?
Thanks. Anna
EDIT: Sure, here is the markup (most of it is generated automatically by the system when adding the Login control); you will notice a button LoginButton integrated in the Login:
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:Panel ID="searchPanel" runat="server" DefaultButton="login1$LoginButton">
<asp:Login ID="Login1" runat="server"
FailureText="Logarea a esuat. Reincercati!" LoginButtonText="Logati-va!"
PasswordLabelText="Parola:"
PasswordRequiredErrorMessage="Trebuie sa introduceti parola."
RememberMeText="Tine-ma minte!" TitleText="Logare"
UserNameLabelText="Nume de utilizator:"
UserNameRequiredErrorMessage="Trebuie sa introduceti numele de utilizator.">
<LayoutTemplate>
<table border="0" cellpadding="1" cellspacing="0"
style="border-collapse:collapse;">
<tr>
<td>
<table border="0" cellpadding="0">
<tr>
<td align="center" colspan="2">
Logare</td>
</tr>
<tr>
<td align="right">
<asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName">Nume
de utilizator:</asp:Label>
</td>
.........
<tr>
<td align="right" colspan="2">
<asp:Button ID="LoginButton" runat="server" CommandName="Login"
Text="Logati-va!" ValidationGroup="Login1" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
</asp:Login>
</asp:Panel>
</asp:Content>
The code-behind goes liek this:
namespace Cinemax
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//userTextBox.Focus(); // this sets the focus on the username textbox when the page loads
this.Title = CinemaxConfiguration.SiteName + ": Login";
}
protected void LoginButton_Click(object sender, EventArgs e)
{
TextBox userTextBox = (TextBox)Login1.FindControl("UserName");
TextBox userPassword = (TextBox)Login1.FindControl("Password");
//Button loginBtn = (Button)Login1.FindControl("LoginButton");
userTextBox.Text = "You pressed me";
if (User1.ConnAttempt(userTextBox.Text, userPassword.Text) == 1)
{
Session["User"] = userTextBox.Text;
Response.Redirect("Catalog.aspx");
}
else
{
}
}
}
}
Is the TestBox an ASP server control, and is runat=Server?
I might be wrong, but do you ever actually bind it back to the control.
You are creating a new textbox that is initialised from your login control.
You then set the text of that textbox, but i dont think thta will bind it back to the control itself.
If you debug the application, does it show that the text gets set?
also, do you have something in the Page_Load method that sets the text box value? you should put things in a
if(!IsPostBack)
{
userTextBox.Text = ""
}
statement
check if your control is runat=server and you have binded the control to the event
this.LoginButton.Click += new System.EventHandler(this.LoginButton_Click);
In your login control check if you are setting some value of userTextBox in Page_Load or any other event, as it appears that its value is being set from somewhere else.
you have to bind it to the Form. . .

how to display database information (evals? labels? literals?)

I have the following asp.net page
<form id="form1" runat="server">
<asp:Button id="display_button" runat="server" Text="Display" OnClick="Button1_Click" />
<asp:Button id="edit_button" runat="server" Text="Edit" OnClick="Button2_Click" />
<asp:Button id="save_button" runat="server" Text="Save" OnClick="Button3_Click" Visible="false" />
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<asp:MultiView id="MultiView1" runat="server" ActiveViewIndex="0">
<asp:View id="View1" runat="server">
<asp:FormView id="view_program" runat="server">
<ItemTemplate>
<tr>
<td class="add_border_bold" nowrap">Status</td>
<td width="100%" class="add_border">
<img src="images/<%# Eval("status").ToString().Trim() %>_light_16.gif" alt="status" />
</td>
</tr>
<tr>
<td class="add_border_bold" nowrap">Short Title</td>
<td width="100%" class="add_border">
<%# Eval("short_title") %>
</td>
</tr>
</ItemTemplate>
</asp:FormView>
</asp:View>
<asp:View id="View2" runat="server">
<asp:FormView id="edit_program" runat="server">
<ItemTemplate>
<tr>
<td class="add_border_bold"nowrap">Status </td>
<td width="100%" class="add_border">
<asp:DropDownList id="p_status" runat="server"></asp:DropDownList>
</td>
</tr>
<tr>
<td class="add_border_bold" nowrap">Short Title</td>
<td width="100%" class="add_border">
<asp:TextBox runat="server" id="short_title" />
</td>
</tr>
</ItemTemplate>
</asp:FormView>
</asp:View>
</form>
with the following code behind page
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
namespace TM_non_deploy
{
public partial class Program : System.Web.UI.Page
{
protected Label Label1;
protected Person myPerson;
protected TestProgram myProgram;
List<TestProgram> program = null;
protected void Page_Load(object sender, EventArgs e)
{
try
{
myPerson = new Person("user");
myProgram = new TestProgram("999");
//needs to be done to refresh info on page
program = new List<TestProgram> { myProgram };
view_program.DataSource = program;
view_program.DataBind();
if (!IsPostBack)
{
//create controls and bind data
edit_program.DataSource = program;
edit_program.DataBind();
DropDownList p_status = edit_program.FindControl("p_status") as DropDownList;
p_status.Items.Add(new ListItem("Green"));
p_status.Items.Add(new ListItem("Yellow"));
p_status.Items.Add(new ListItem("Red"));
p_status.SelectedValue = myProgram.Status.Trim();
TextBox short_title = edit_program.FindControl("short_title") as TextBox;
short_title.Width = 200;
short_title.Text = myProgram.Short_Title.Trim();
}
}
catch (Exception ex)
{
Response.Write(ex);
Label1.Text = ex.ToString();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
MultiView1.SetActiveView(View1);
save_button.Visible = false;
}
protected void Button2_Click(object sender, EventArgs e)
{
MultiView1.SetActiveView(View2);
save_button.Visible = true;
}
protected void Button3_Click(object sender, EventArgs e)
{
DropDownList c_status = edit_program.FindControl("p_status") as DropDownList;
myProgram.Status = c_status.SelectedValue;
bool update = myProgram.SaveTestProgram();
if (update)
{
Label1.Text = "Saved!";
//needs to be done to refresh info on page
program = new List<TestProgram> { myProgram };
view_program.DataSource = program;
view_program.DataBind();
MultiView1.SetActiveView(View1);
save_button.Visible = false;
}
else
{
Label1.Text = "Error Saving";
}
}
}
}
basically, it is one page that both displays the fields, and then on a button click displays the editable version of all those fields. my question is, should i be displaying all of the information like i am now, with evals? or should i switch to labels, or literals, or something else entirely? i want to know before i get too far and have to undo a lot of work.
there will end up being a ton of fields on this page, all types from checkboxes to dropdowns to multiline textboxes, so i want to make sure i pick the path that works best for displaying all of those different kinds of data, even though in this example i am only displaying small text information.
If you just need to display text, there's no reason not to just use your <%# Eval("title") %>
One thing that should be noted though, is that it's better to cast your DataItem and access the properties that way instead of Eval as Eval has to use reflection and is more costly (maybe to the being of actually being noticeable if you have a lot of stuff repeated).
Use: <%# (Container.DataItem as SomeObject).Title %> instead of <%# Eval("Title") %>
Kind of outside the scope of your question but just a side note. :)
I wouldn't go for ServerSide Controls (Labels/Literals) unless you need formatting or to change the control values in other server side events. They just add to ViewState (unless ViewState is disabled on those Controls).
Coming to whether it's the right approach, I would suggest you use EditItemTemplate of FormView instead of 2 FormViews in Different Views & a MultiView Control!

Categories

Resources