When internationalising a website, you really do care about what HTML gets placed into your code - in this particular case injecting <span> tags into a table with both left-to-right text and right-to-left text really REALLY confuses Firefox and Opera as to which direction to put the text. The solution to this, we discovered, was to wrap the text in Paragraph tags, to give the browser some kind of a hint that this text should be lifted out of the RTL flow and LTRted.
Problem:
The text was placed using a custom control, which then used the System.Web.UI.Webcontrols.Label control to place the text, which we discovered was the culprit behind the offending span tags.
Digging around in the framework source code I discovered the offending tags were not, as we had thought, placed by Label itself but by System.Web.UI.Webcontrols.WebControl. Not having time to change said control to a Literal (which did not inherit from WebControl, thus would also loose all the associated functionality along with that, like CssClass) we opted to try and change the way Label worked and spit out P tags instead.
Now, anyone who has tried to change the functionality of the Framework will know alot of things in there are private and internal which makes it a proper pain in the ass to change anything Microsoft don't want you to change and in this case I can see why - it uses the surrounding tag to add the CssClass functionality et all, and needs SOMETHING to place there, plus if you surround the text with the wrong thing, it will try to add the class= attribute (ok, I know class is pretty much avaliable to any tag, but there could be other things it needs it for) and could screw things up - but I know that, and I'm building my own damn controls, with their own damn protection - so I want to change the damn tag.
Ok, So I grab the Label.cs and WebControl.cs files, and start digging through them and discover that the Tag it surround the surrounding tags are inserted on Render() from the tagKey private field. So we cant change that without overriding Render(), which I have a great dislike for doing (if in the future they add something and I've overriden it, things could break, so I like to target the specific functionality instead) so we need to find how to mess with the tagKey member field.
tagKey is set via the constructor of the class thusly:
1: protected WebControl() : this(HtmlTextWriterTag.Span) {
2: }
3:
4: public WebControl(HtmlTextWriterTag tag) {
5: tagKey = tag;
6: }
7:
8: protected WebControl(string tag) {
9: tagKey = HtmlTextWriterTag.Unknown;
10: tagName = tag;
11: }
which would seem to be easy to change but wait! Label implements its constructors like so:
1: public Label() {
2: }
3:
4: internal Label(HtmlTextWriterTag tag) : base(tag) {
5: }
Which...is a problem. They have blocked all our access to the string constructor (as constructors don't inherit without a similar constructor in the inheriting class, with the base() keyword) and made the HtmlTextWriterTag constructor internal...which means we can'tdo anything with it.
Fortunatly, the tagKey private field is encapsulatedwith a protected virtual public property as so:
1: [
2: Browsable(false),
3: DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
4: ]
5: protected virtual HtmlTextWriterTag TagKey {
6: get {
7: return tagKey;
8: }
9: }
Win! We can override this, add our own private field, rebuild our constructorsand we are set. The code follows:
1: public class FlexiLabel : Label
2: {
3: private HtmlTextWriterTag tagKeyOverride = HtmlTextWriterTag.Span;
4:
5: public HtmlTextWriterTag TagKeyOverride
6: {
7: get { return tagKeyOverride; }
8: set { tagKeyOverride = value; }
9: }
10:
11: [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
12: protected override HtmlTextWriterTag TagKey
13: {
14: get
15: {
16: return tagKeyOverride;
17: }
18: }
19:
20: public FlexiLabel()
21: : base()
22: {
23: }
24:
25: public FlexiLabel(HtmlTextWriterTag inTagKey)
26: : base()
27: {
28: tagKeyOverride = inTagKey;
29: }
30: }
It's a pretty easy solution - but it's a pain digging through the framework src to figure it out. Part of me wishes MS would make thigns a bit easier to navigate, but most of me have alot of respect and thanks to MS for releasing their source, it makes my life SO much easier.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5