diff options
Diffstat (limited to 'Xamarin.Forms.Platform.WP8/LabelRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.WP8/LabelRenderer.cs | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WP8/LabelRenderer.cs b/Xamarin.Forms.Platform.WP8/LabelRenderer.cs new file mode 100644 index 00000000..86c68adf --- /dev/null +++ b/Xamarin.Forms.Platform.WP8/LabelRenderer.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Media; + +namespace Xamarin.Forms.Platform.WinPhone +{ + public static class FormattedStringExtensions + { + public static IEnumerable<Inline> ToInlines(this FormattedString formattedString) + { + foreach (Span span in formattedString.Spans) + yield return span.ToRun(); + } + + public static Run ToRun(this Span span) + { + var run = new Run { Text = span.Text }; + + if (span.ForegroundColor != Color.Default) + run.Foreground = span.ForegroundColor.ToBrush(); + + if (!span.IsDefault()) + run.ApplyFont(span.Font); + + return run; + } + } + + public class LabelRenderer : ViewRenderer<Label, TextBlock> + { + bool _fontApplied; + + protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize) + { + if (Element == null) + return finalSize; + double childHeight = Math.Max(0, Math.Min(Element.Height, Control.DesiredSize.Height)); + var rect = new Rect(); + + switch (Element.VerticalTextAlignment) + { + case TextAlignment.Start: + break; + default: + case TextAlignment.Center: + rect.Y = (int)((finalSize.Height - childHeight) / 2); + break; + case TextAlignment.End: + rect.Y = finalSize.Height - childHeight; + break; + } + rect.Height = childHeight; + rect.Width = finalSize.Width; + Control.Arrange(rect); + return finalSize; + } + + protected override void OnElementChanged(ElementChangedEventArgs<Label> e) + { + base.OnElementChanged(e); + + var textBlock = new TextBlock { Foreground = (Brush)System.Windows.Application.Current.Resources["PhoneForegroundBrush"] }; + UpdateText(textBlock); + UpdateColor(textBlock); + UpdateAlign(textBlock); + UpdateFont(textBlock); + UpdateLineBreakMode(textBlock); + SetNativeControl(textBlock); + } + + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == Label.TextProperty.PropertyName || e.PropertyName == Label.FormattedTextProperty.PropertyName) + UpdateText(Control); + else if (e.PropertyName == Label.TextColorProperty.PropertyName) + UpdateColor(Control); + else if (e.PropertyName == Label.HorizontalTextAlignmentProperty.PropertyName || e.PropertyName == Label.VerticalTextAlignmentProperty.PropertyName) + UpdateAlign(Control); + else if (e.PropertyName == Label.FontProperty.PropertyName) + UpdateFont(Control); + else if (e.PropertyName == Label.LineBreakModeProperty.PropertyName) + UpdateLineBreakMode(Control); + base.OnElementPropertyChanged(sender, e); + } + + void UpdateAlign(TextBlock textBlock) + { + if (textBlock == null) + return; + + Label label = Element; + if (label == null) + return; + + textBlock.TextAlignment = label.HorizontalTextAlignment.ToNativeTextAlignment(); + textBlock.VerticalAlignment = label.VerticalTextAlignment.ToNativeVerticalAlignment(); + } + + void UpdateColor(TextBlock textBlock) + { + if (textBlock == null) + return; + + Label label = Element; + if (label != null && label.TextColor != Color.Default) + textBlock.Foreground = label.TextColor.ToBrush(); + else + textBlock.Foreground = (Brush)System.Windows.Application.Current.Resources["PhoneForegroundBrush"]; + } + + void UpdateFont(TextBlock textBlock) + { + if (textBlock == null) + return; + + Label label = Element; + if (label == null || (label.IsDefault() && !_fontApplied)) + return; + + Font fontToApply = label.IsDefault() ? Font.SystemFontOfSize(NamedSize.Medium) : label.Font; + + textBlock.ApplyFont(fontToApply); + _fontApplied = true; + } + + void UpdateLineBreakMode(TextBlock textBlock) + { + if (textBlock == null) + return; + + switch (Element.LineBreakMode) + { + case LineBreakMode.NoWrap: + textBlock.TextTrimming = TextTrimming.None; + textBlock.TextWrapping = TextWrapping.NoWrap; + break; + case LineBreakMode.WordWrap: + textBlock.TextTrimming = TextTrimming.None; + textBlock.TextWrapping = TextWrapping.Wrap; + break; + case LineBreakMode.CharacterWrap: + textBlock.TextTrimming = TextTrimming.WordEllipsis; + textBlock.TextWrapping = TextWrapping.Wrap; + break; + case LineBreakMode.HeadTruncation: + textBlock.TextTrimming = TextTrimming.WordEllipsis; + textBlock.TextWrapping = TextWrapping.NoWrap; + break; + case LineBreakMode.TailTruncation: + textBlock.TextTrimming = TextTrimming.WordEllipsis; + textBlock.TextWrapping = TextWrapping.NoWrap; + break; + case LineBreakMode.MiddleTruncation: + textBlock.TextTrimming = TextTrimming.WordEllipsis; + textBlock.TextWrapping = TextWrapping.NoWrap; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + void UpdateText(TextBlock textBlock) + { + if (textBlock == null) + return; + + Label label = Element; + if (label != null) + { + if (label.FormattedText == null) + textBlock.Text = label.Text; + else + { + FormattedString formattedText = label.FormattedText ?? label.Text; + + textBlock.Inlines.Clear(); + foreach (Inline inline in formattedText.ToInlines()) + textBlock.Inlines.Add(inline); + } + } + } + } +}
\ No newline at end of file |