使ASP.NET移动控件呈现RTL语言

When you're rendering HTML for an Arabic or Hebrew speaking audience (or Farsi, or Divehi, or Urdu, or Syriac) you usually want to change the direction of the entire page, and that's done by adding dir="rtl" to a containing element of your page, typically the HTML outer element if you want the scrollbar to switch from the left to the right. RTL, of course, means Right To Left, as these languages are typically read right to left.

当您为讲阿拉伯语或希伯来语的受众(或波斯语,迪维希语,乌尔都语或叙利亚语)呈现HTML时,通常需要更改整个页面的方向,这可以通过将dir =“ rtl”添加到包含页面元素,如果希望滚动条从左向右切换,通常是HTML外部元素。 RTL当然是从右到左的意思,因为这些语言通常是从右到左阅读。

In ASP.NET 1.x, this was difficult programmatically, necessitating the BODY or HTML tag being runat="server" as you went hunting for it and manually added the dir="rtl" attribute yourself. I talked about this on the blog three years ago.

在ASP.NET 1.x中,这在编程上很困难,必须在寻找BODY或HTML标记时运行runat =“ server”并自己手动添加dir =“ rtl”属性。 三年前,在博客上谈到了这一点

It gets a little easier in ASP.NET 2.0 with the addition of the ContentDirection enumeration/property that's added to the Panel and WebPart controls.

在ASP.NET 2.0中,通过将ContentDirection枚举/属性添加到Panel和WebPart控件中,它变得更加容易。

However, if you're working with the MobileControls, it appears to be quite a bit harder, as the whole "form" metaphor changes. The Mobile stuff in ASP.NET has the notion of multiple "forms" per page where only one is active. It is that active form that does the actual rendering of the <html> element.

但是,如果您使用的是MobileControls,则由于整个“形式”隐喻的变化,它似乎要困难得多。 ASP.NET中的“移动”内容每页有多个“表单”的概念,其中只有一个处于活动状态。 正是活动表单执行了<html>元素的实际呈现。

That means even if you have "<html xmlns="http://www.w3.org/1999/xhtml">" in your ASPX markup, you might end up with just <html> because it is the mobile:Form control that does the rendering via a PageAdapter that inherits from MobileTextWriter.

这意味着即使您的ASPX标记中包含“ <html xmlns =“ http://www.w3.org/1999/xhtml”>“,您也可能只会得到<html>,因为它是mobile:Form控件通过从MobileTextWriter继承的PageAdapter进行渲染。

The mobile stuff in ASP.NET is very powerful, but very obtuse. I wanted to add dir="rtl" programmatically, but there's no support for custom attributes on a mobile:Form, and the Alignment="right" attribute is semantically different from dir="rtl."

ASP.NET中的移动功能非常强大,但很钝。 我想以编程方式添加dir =“ rtl”,但是在mobile:Form上不支持自定义属性,并且Alignment =“ right”属性在语义上与dir =“ rtl不同。

Here's a page with Hebrew on it that has dir="ltr," which is also the default if you include no dir= attribute. Notice that the there are three labels for Account Name, Number, and Amount, and the labels that are within strings that include numbers have the labels on the RIGHT with the colons (:) within the label to the LEFT of the label.

这是一个上面带有希伯来语的页面,上面带有dir =“ ltr”,如果您不包含dir =属性,这也是默认设置。 请注意,“帐户名称”,“数字”和“金额”有三个标签,并且在包含数字的字符串中的标签在标签的右侧带有带冒号(:)的标签,在标签的左侧。

That is, NUMBER COLON LABEL.

即NUMBER COLON LABEL。

While the line without numbers, or more specifically with English included has the Hebrew labels with a colon to the right.

不带数字的行或更确切地说带英语的行在希伯来语标签的右侧带有冒号。

That is LABEL COLON ENGLISHWORD.

那是LABEL COLON ENGLISHWORD。

This is because the browser, independent of dir= attribute (or lack of one) is trying to "do the right thing" with this mixed content page (that happens to be Unicode). You can override this behavior with markup like dir= or with CSS styles like unicode-bidi: bidi-override or unicode-bidi: embed. More details on that are in the very good W3C I18N FAQ on CSS vs. Markup for BIDI (BiDirectional) support. In this post, I'm just talking about markup.

这是因为独立于dir =属性(或缺少dir =属性)的浏览器正在尝试对该混合内容页面(恰好是Unicode)“做正确的事”。 您可以使用dir =等标记或CSS样式(例如unicode-bidi:bidi-override或unicode-bidi:embed)来覆盖此行为。 关于CSS的更好W3C I18N常见问题与BIDI(BiDirectional)支持的标记有关的更多详细信息。 在这篇文章中,我只是在谈论标记。

I tried to do this:

我尝试这样做:

this.ActiveForm.CustomAttributes.Add("dir","rtl")

this.ActiveForm.CustomAttributes.Add(“ dir”,“ rtl”)

but I got this funny error message. Why funny you ask? Because it's telling me that I can't set dir="rtl" but if you do a view source (or just notice where the scrollbar is!) you'll see that it DID in fact successfully apply dir="rtl". 

但是我得到了这个有趣的错误消息。 你问为什么有趣? 因为它告诉我不能设置dir =“ rtl”,但是如果您执行视图源(或仅注意滚动条的位置!),您会发现它实际上已成功应用dir =“ rtl”。

This error goes away if I add this to my web.config.

如果将其添加到我的web.config中,此错误将消失。

<mobileControls cookielessDataDictionaryType="System.Web.Mobile.CookielessData" allowCustomAttributes="true"/>

<mobileControls cookielessDataDictionaryType =“ System.Web.Mobile.CookielessData” allowCustomAttributes =“ true” />

However, the CustomAttributes bag isn't the way to effectively manipulate the rendering of the mobile controls. 

但是,CustomAttributes包不是有效操纵移动控件呈现的方法。

Instead, I needed creating my own PageAdapter, specifically a DirectionAwareHtmlPageAdapter:

相反,我需要创建自己的PageAdapter,特别是DirectionAwareHtmlPageAdapter:

   1:  namespace Corillian.Web.Mobile
   2:  {
   3:      public class DirectionAwareHtmlPageAdapter : System.Web.UI.MobileControls.Adapters.HtmlPageAdapter
   4:      {
   5:          public override void RenderForm(System.Web.UI.MobileControls.Adapters.HtmlMobileTextWriter writer, System.Web.UI.MobileControls.Form form)
   6:          {
   7:              writer.BeginFile(this.GetFormUrl(form), "text/html", this.Page.Response.Charset);
   8:   
   9:              //Added by me to support RTL - sucks!
  10:              writer.WriteBeginTag("html");
  11:              if (Corillian.Voyager.Web.Globalization.CurrentCulture.IsRightToLeftCulture(Thread.CurrentThread.CurrentUICulture.Name))
  12:              {
  13:                  writer.WriteAttribute("dir", "rtl");
  14:              }
  15:              writer.Write(System.Web.UI.MobileControls.Adapters.HtmlMobileTextWriter.TagRightChar);
  16:   
  17:              form.RenderControl(writer);
  18:              if (this.Device.RequiresDBCSCharacter)
  19:              {
  20:                  writer.Write("<!--\u3000-->");
  21:              }
  22:              writer.WriteEndTag("html");
  23:              writer.EndFile();
  24:          }
  25:   
  26:      }
  27:  }

This kind of sucks, because the only CUSTOM code is between line 9 and 15. The rest is copy/pasted directly out of HtmlPageAdapter using Reflector. I really think the mobile guys (and the whole ASP.NET team) should have considered the need for dynamically changing page direction for both mobile and desktop HTML. Perhaps this adapter technique is what they recommend, or perhaps there's a hidden or simpler way that I haven't figured out yet. If so, I'll post that and retract all this silliness...but until then...

这种情况很糟糕,因为唯一的CUSTOM代码在第9行和第15行之间。其余的代码是使用Reflector直接从HtmlPageAdapter复制/粘贴出来的。 我真的认为移动人员(和整个ASP.NET团队)应该已经考虑过需要动态更改移动HTML和桌面HTML的页面方向。 他们可能会推荐这种适配器技术,或者也许我还没有找到一种隐藏的或更简单的方法。 如果是这样,我将发布该帖子并收回所有这些愚蠢的行为……但是直到那时……

You'll notice the call to a custom method called "IsRightToLeftCulture." I couldn't find anywhere in the Globalization namespace where one could just ASK a CultureInfo object if it referred to a RTL or LTR language. I know this was the case in .NET 1.1, and I'm 99% sure it doesn't exist in .NET 2.0 either. I'd love to be told otherwise.

您会注意到对名为“ IsRightToLeftCulture”的自定义方法的调用。 我找不到全球化命名空间中的任何地方,只要它引用了RTL或LTR语言,就可以询问CultureInfo对象。 我知道在.NET 1.1中就是这种情况,而且我99%肯定它在.NET 2.0中也不存在。 否则我会被告知。

UPDATE: I can use System.Globalization.CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft() in .NET 2.0 so there's no need for this function under 2.0.

更新:我可以在.NET 2.0中使用System.Globalization.CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft(),因此在2.0下不需要此功能。

So, here is this little gem, but what price my immortal soul?

那么,这是这个小宝石,但是我不朽的灵魂要付出多少代价呢?

   1:  /// <summary>
   2:  /// Returns true if the supplied culture (or its parent) is read from Right-to-Left
   3:  /// </summary>
   4:  /// <returns>True if the supplied culture (or its parent) is read from Right-to-Left</returns>
   5:  public static bool IsRightToLeftCulture(string culture)
   6:  {
   7:      //Only look at the parent culture.
   8:      string myCulture = culture.Split(new char[]{'-'})[0];
   9:      switch (myCulture)
  10:      {
  11:          case "ar":        //Arabic
  12:          case "fa":        //Farsi
  13:          case "div":        //Divehi
  14:          case "syr":        //Syriac
  15:          case "he":        //Hebrew
  16:          case "ur":        //Urdu
  17:              return true;
  18:      }
  19:      return false;
  20:  }

Now that I have this new PageAdapter, I need to tell the world about it by editing my web.config:

现在有了这个新的PageAdapter,我需要通过编辑web.config向全世界介绍它:

<mobileControls cookielessDataDictionaryType="System.Web.Mobile.CookielessData" allowCustomAttributes="true">
    <device name="DirectionAwareHtmlDeviceAdapters" inheritsFrom="HtmlDeviceAdapters" pageAdapter="Corillian.Web.Mobile.DirectionAwareHtmlPageAdapter,App_Code"/>
</mobileControls>

<mobileControls cookielessDataDictionaryType =“ System.Web.Mobile.CookielessData” allowCustomAttributes =“ true”> <device name =“ DirectionAwareHtmlDeviceAdapters” InheritsFrom =“ HtmlDeviceAdapters” pageAdapter =“ Corillian.Web.Mobile.DirectionAwareHtmlPageAdapter,App_Code ” /> </ mobileControls>

Note the Assembly Qualified Name (QN) in the pageAdapter attribute. See how the ClassName,AssemblyName uses "App_Code" for the assembly name? That's because my DirectionAwareHtmlDeviceAdapter.cs file is in my App_Code directory. That's one of the well-known directories that automatically gets compiled when there's a .cs file in it. The assembly that's generated is App_Code.dll. A little confusing. Alternatively, I could have put the class in a separate and more manually-compiled assembly and referenced it from there.

请注意pageAdapter属性中的程序集合格名称(QN)。 看看ClassName,AssemblyName如何使用“ App_Code”作为程序集名称吗? 那是因为我的DirectionAwareHtmlDeviceAdapter.cs文件在App_Code目录中。 这是其中包含.cs文件时会自动编译的著名目录之一。 生成的程序集是App_Code.dll。 有点混乱。 或者,我可以将类放在一个单独的,更手动编译的程序集中,然后从那里引用它。

Now that the dir="rtl" is added to the HTML element the whole page renders correctly with the labels and all page elements not only right aligned, but rendered right-to-left. The direction changes dynamically based on the browser's Accept-Language HTTP Header.

现在,将dir =“ rtl”添加到HTML元素中,整个页面将正确显示,带有标签,并且所有页面元素不仅右对齐,而且从右向左呈现。 方向根据浏览器的接受语言HTTP标头动态变化。

Thanks to Patrick Cauldwell and Travis Illig for their help debugging today!

感谢Patrick CauldwellTravis Illig今天提供的调试帮助!

翻译自: https://www.hanselman.com/blog/making-the-aspnet-mobile-controls-render-rtl-languages

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值