Reputation: 85
I have a simple language switcher through a drop down list, however I would like to switch to a list. As far as I know, AutoPostBack is not supported for bulleted list but only the PostBack property. In this case, using postback leads the switcher not to function anymore. Is there a way to come over this?
<asp:DropDownList ID="cmbCulture" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="cmbCulture_SelectedIndexChanged"
CssClass="lang_switcher"
DisplayMode="LinkButton">
<asp:ListItem Value="de-DE">DE</asp:ListItem>
<asp:ListItem Value="en-US">EN</asp:ListItem>
</asp:DropDownList>
And here is the code:
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
HttpCookie cultureCookie = Request.Cookies["Culture"];
string cultureCode = (cultureCookie != null) ? cultureCookie.Value : null;
if (!string.IsNullOrEmpty(cultureCode))
{
cmbCulture.SelectedValue = cultureCode;
}
}
}
protected void cmbCulture_SelectedIndexChanged(object sender, EventArgs e)
{
//Save Current Culture in Cookie- will be used in InitializeCulture in BasePage
Response.Cookies.Add(new HttpCookie("Culture", cmbCulture.SelectedValue));
Response.Redirect(Request.Url.AbsolutePath); //Reload and Clear PostBack Data
}
}
So I would like to achieve something like:
front-end:
<asp:BulletedList ID="cmbCulture" runat="server" PostBack="True" OnSelectedIndexChanged="cmbCulture_SelectedIndexChanged" DisplayMode="LinkButton">
<asp:ListItem Value="en-US">EN</asp:ListItem>
<asp:ListItem Value="de-DE">DE</asp:ListItem>
</asp:BulletedList>
back-end:
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
HttpCookie cultureCookie = Request.Cookies["Culture"];
string cultureCode = (cultureCookie != null) ? cultureCookie.Value : null;
if (!string.IsNullOrEmpty(cultureCode))
{
cmbCulture.SelectedItem.Value = cultureCode;
}
}
}
protected void cmbCulture_SelectedIndexChanged(object sender, EventArgs e)
{
//Save Current Culture in Cookie- will be used in InitializeCulture in BasePage
Response.Cookies.Add(new HttpCookie("Culture", cmbCulture.SelectedItem.Value));
Response.Redirect(Request.Url.AbsolutePath); //Reload and Clear PostBack Data
}
}
SelectedItem.Value drops an error of "Object reference not set to an instance of an object." Is there a way to get the value of the clicked listitem in my bulletedlist? This may be the solution.
Upvotes: 0
Views: 2221
Reputation:
There are so many ways to do this, depending on what the rest of your logic is, you could do it as simple as this on the front end:
<ul>
<li><asp:HyperLink ID="hypDE" runat="server" Text="DE" NavigateUrl="yourpage.aspx?culture=DE" /></li>
<li><asp:HyperLink ID="hypUS" runat="server" Text="US" NavigateUrl="yourpage.aspx?culture=US" /></li>
</ul>
And in the codebehind of yourpage.aspx, you can set the appropriate culture by doing something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string culture = Request.QueryString["culture"];
}
}
But there are much more ways to do it, you could use basically any datacontrol, such as a listview, a repeater,...
If you consider making this more dynamic by for example loading the sitecultures from an xml file or from a database or whatever, you should use a data control. Here's an example with a repeater:
Front-end:
<asp:Repeater ID="repCultures" runat="server" OnItemDataBound="repCultures_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<li>
<asp:HyperLink ID="hypCulture" runat="server" />
</li>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
back-end:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//This is where you would get your cultures out of an xml or database
//I'm using a non-dynamic list to make a simple representation
List<string> cultures = new List<string>() { "de-DE", "en-US", "en-UK" };
repCultures.DataSource = cultures;
repCultures.DataBind();
}
}
protected void repCultures_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
string culture = e.Item.DataItem as string;
HyperLink hypCulture = e.Item.FindControl("hypCulture") as HyperLink;
hypCulture.Text = culture;
hypCulture.NavigateUrl = string.Format("~/yourpage.aspx?culture={0}", culture);
}
}
Then again on yourpage.aspx you will us the querystring to fetch the culture you'd like.
Again, there are so many ways on doing this so if this doesn't work out for you let me know a bit more about your project and I'll suggest a better way of doing it.
Hopefully this is helpful!
EDIT:
firstly change the event to this:
front-end:
<asp:BulletedList ID="cmbCulture" runat="server" OnClick="cmbCulture_Click" DisplayMode="LinkButton">
back-end:
protected void cmbCulture_Click(object sender, BulletedListEventArgs e)
{
//Save Current Culture in Cookie- will be used in InitializeCulture in BasePage
Response.Cookies.Add(new HttpCookie("Culture", cmbCulture.Items[e.Index].Value));
Response.Redirect(Request.Url.AbsolutePath); //Reload and Clear PostBack Data
}
this should work.
Upvotes: 3