diff options
author | E.Z. Hart <hartez@users.noreply.github.com> | 2016-08-30 12:12:27 -0600 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-08-30 11:12:27 -0700 |
commit | 1b7250167ff027bbd5ce3d2950a3e3495a13a5f7 (patch) | |
tree | bc219a8dada47527b2252fb7a07f8158b6f24701 | |
parent | 0bc22bda64afedbca09416cdccc77ce4ddbe522d (diff) | |
download | xamarin-forms-1b7250167ff027bbd5ce3d2950a3e3495a13a5f7.tar.gz xamarin-forms-1b7250167ff027bbd5ce3d2950a3e3495a13a5f7.tar.bz2 xamarin-forms-1b7250167ff027bbd5ce3d2950a3e3495a13a5f7.zip |
Use character truncation in Windows (#321)
Change layout order ViewCells on Windows to correct label length layout issues
Add extra layout pass on ViewCell load to make cells without margins visible
6 files changed, 249 insertions, 14 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42519.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42519.cs new file mode 100644 index 00000000..822943ce --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42519.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Controls +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 42519, "Text Truncation in UWP")] + public class Bugzilla42519 : TestNavigationPage + { + public static readonly string LongLabelSingle = + "longleftlabelthequickbrownfoxjumpedoverthelazydogsthequickbrownfoxjumpedoverthelazydogs"; + + public static readonly string LongLabelWords = + "long left label the quick brown fox jumped over the lazy dogs the quick brown fox jumped over the lazy dogs"; + + protected override void Init() + { + PushAsync(Menu()); + } + + static ContentPage CreateContent(Type cellType) + { + return new ContentPage { Content = CreateListView(new DataTemplate(cellType)) }; + } + + static ListView CreateListView(DataTemplate template) + { + var items = new List<_42519Item> + { + new _42519Item + { + TitleLeft = LongLabelWords, + TitleRight = "32522665", + SubLeft = "LeftLabel", + SubRight = "Long Right Label" + }, + new _42519Item + { + TitleLeft = LongLabelSingle, + TitleRight = "12552665222", + SubLeft = "LeftLabel", + SubRight = "Long Right Label" + }, + new _42519Item + { + TitleLeft = LongLabelSingle, + TitleRight = "225565365", + SubLeft = "LeftLabel", + SubRight = "Long Right Label" + }, + new _42519Item + { + TitleLeft = LongLabelWords, + TitleRight = "215565365", + SubLeft = "LeftLabel", + SubRight = "Long Right Label" + } + }; + + return new ListView + { + HasUnevenRows = true, + ItemTemplate = template, + ItemsSource = items + }; + } + + static ContentPage Menu() + { + var page = new ContentPage(); + + var heading = new Label { Text = "Select an option below to see text tail truncation in various contexts." }; + + if (Device.Idiom == TargetIdiom.Phone) + { + heading.Text += " Rotating the phone between portrait and landscape mode should not cause the ellipsis to disappear from truncated text."; + } + + var labelButton = new Button { Text = "Single Label" }; + var gridButton = new Button { Text = "Single Grid" }; + var listWithLabelsButton = new Button { Text = "ListView with Label ViewCell" }; + var listWithGridsButton = new Button { Text = "ListView with Grid ViewCell" }; + + labelButton.Clicked += (sender, args) => + { + var content = new Label { Text = LongLabelSingle, LineBreakMode = LineBreakMode.TailTruncation }; + page.Navigation.PushAsync(new ContentPage { Content = content }); + }; + + gridButton.Clicked += (sender, args) => + { + var content = new ContentPage + { + Content = _42519CustomViewCellGrid.CreateGrid(), + BindingContext = new _42519Item + { + TitleLeft = LongLabelSingle, + TitleRight = "32522665", + SubLeft = "LeftLabel", + SubRight = "Long Right Label" + } + }; + page.Navigation.PushAsync(content); + }; + + listWithLabelsButton.Clicked += + (sender, args) => { page.Navigation.PushAsync(CreateContent(typeof(_42519CustomViewCellLabel))); }; + + listWithGridsButton.Clicked += + (sender, args) => { page.Navigation.PushAsync(CreateContent(typeof(_42519CustomViewCellGrid))); }; + + page.Content = new StackLayout + { + Children = + { + heading, + labelButton, + gridButton, + listWithLabelsButton, + listWithGridsButton + } + }; + + return page; + } + + [Preserve(AllMembers = true)] + internal class _42519Item + { + public string SubLeft { get; set; } + + public string SubRight { get; set; } + + public string TitleLeft { get; set; } + + public string TitleRight { get; set; } + } + + [Preserve(AllMembers = true)] + internal class _42519CustomViewCellGrid : ViewCell + { + public _42519CustomViewCellGrid() + { + View = CreateGrid(); + } + + public static Grid CreateGrid() + { + var grid = new Grid + { + VerticalOptions = LayoutOptions.FillAndExpand, + RowDefinitions = + { + new RowDefinition { Height = new GridLength(24, GridUnitType.Absolute) }, + new RowDefinition { Height = new GridLength(24, GridUnitType.Absolute) } + }, + ColumnDefinitions = + { + new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }, + new ColumnDefinition { Width = GridLength.Auto } + }, + Padding = new Thickness(16, 12, 16, 12) + }; + var leftLabel = new Label + { + LineBreakMode = LineBreakMode.TailTruncation + }; + leftLabel.SetBinding(Label.TextProperty, "TitleLeft"); + + var rightLabel = new Label + { + FontSize = 20, + HorizontalOptions = LayoutOptions.End + }; + rightLabel.SetBinding(Label.TextProperty, "TitleRight"); + + var subLeft = new Label + { + LineBreakMode = LineBreakMode.TailTruncation + }; + subLeft.SetBinding(Label.TextProperty, "SubLeft"); + + var subRight = new Label + { + HorizontalOptions = LayoutOptions.End + }; + subRight.SetBinding(Label.TextProperty, "SubRight"); + + grid.Children.Add(leftLabel, 0, 0); + grid.Children.Add(rightLabel, 1, 0); + grid.Children.Add(subLeft, 0, 1); + grid.Children.Add(subRight, 1, 1); + + return grid; + } + } + + [Preserve(AllMembers = true)] + internal class _42519CustomViewCellLabel : ViewCell + { + public _42519CustomViewCellLabel() + { + var leftLabel = new Label + { + LineBreakMode = LineBreakMode.TailTruncation + }; + + leftLabel.SetBinding(Label.TextProperty, "TitleLeft"); + + View = leftLabel; + } + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 7a46c880..c0f5d33a 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -122,6 +122,7 @@ <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42075.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42329.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42364.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42519.cs" /> <Compile Include="$(MSBuildThisFileDirectory)CarouselAsync.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla34561.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla34727.cs" /> diff --git a/Xamarin.Forms.Core/Layout.cs b/Xamarin.Forms.Core/Layout.cs index 8c0d1625..87a3453b 100644 --- a/Xamarin.Forms.Core/Layout.cs +++ b/Xamarin.Forms.Core/Layout.cs @@ -417,7 +417,7 @@ namespace Xamarin.Forms bool ShouldLayoutChildren() { - if (!LogicalChildrenInternal.Any() || Width <= 0 || Height <= 0 || !IsVisible || !IsNativeStateConsistent || DisableLayout) + if (Width <= 0 || Height <= 0 || !LogicalChildrenInternal.Any() || !IsVisible || !IsNativeStateConsistent || DisableLayout) return false; foreach (Element element in VisibleDescendants()) diff --git a/Xamarin.Forms.Platform.WP8/ViewToRendererConverter.cs b/Xamarin.Forms.Platform.WP8/ViewToRendererConverter.cs index 28f5f8c4..50ac3352 100644 --- a/Xamarin.Forms.Platform.WP8/ViewToRendererConverter.cs +++ b/Xamarin.Forms.Platform.WP8/ViewToRendererConverter.cs @@ -41,6 +41,7 @@ namespace Xamarin.Forms.Platform.WinPhone { frameworkElement.Loaded += (sender, args) => { + (_view as Layout)?.ForceLayout(); ((IVisualElementController)_view).InvalidateMeasure(InvalidationTrigger.MeasureChanged); InvalidateMeasure(); }; @@ -61,16 +62,22 @@ namespace Xamarin.Forms.Platform.WinPhone protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize) { var content = Content as FrameworkElement; - content?.Measure(availableSize); Size request = _view.Measure(availableSize.Width, availableSize.Height, MeasureFlags.IncludeMargins).Request; System.Windows.Size result; if (_view.HorizontalOptions.Alignment == LayoutAlignment.Fill && !double.IsInfinity(availableSize.Width) && availableSize.Width != 0) + { result = new System.Windows.Size(availableSize.Width, request.Height); + } else + { result = new System.Windows.Size(request.Width, request.Height); + } + + _view.Layout(new Rectangle(0, 0, result.Width, result.Height)); + + content?.Measure(availableSize); - _view.Layout(new Rectangle(0, 0, result.Width, result.Width)); return result; } } diff --git a/Xamarin.Forms.Platform.WinRT/LabelRenderer.cs b/Xamarin.Forms.Platform.WinRT/LabelRenderer.cs index cb33cde9..1f2f861d 100644 --- a/Xamarin.Forms.Platform.WinRT/LabelRenderer.cs +++ b/Xamarin.Forms.Platform.WinRT/LabelRenderer.cs @@ -165,7 +165,7 @@ namespace Xamarin.Forms.Platform.WinRT textBlock.TextWrapping = TextWrapping.NoWrap; break; case LineBreakMode.TailTruncation: - textBlock.TextTrimming = TextTrimming.WordEllipsis; + textBlock.TextTrimming = TextTrimming.CharacterEllipsis; textBlock.TextWrapping = TextWrapping.NoWrap; break; case LineBreakMode.MiddleTruncation: diff --git a/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs b/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs index 38950522..3d5906dc 100644 --- a/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs +++ b/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs @@ -2,6 +2,7 @@ using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; +using Xamarin.Forms.Internals; #if WINDOWS_UWP @@ -41,6 +42,8 @@ namespace Xamarin.Forms.Platform.WinRT { readonly View _view; + FrameworkElement FrameworkElement => Content as FrameworkElement; + public WrapperControl(View view) { _view = view; @@ -54,9 +57,17 @@ namespace Xamarin.Forms.Platform.WinRT Content = renderer.ContainerElement; // make sure we re-measure once the template is applied - FrameworkElement frameworkElement = renderer.ContainerElement; - if (frameworkElement != null) - frameworkElement.Loaded += (sender, args) => InvalidateMeasure(); + if (FrameworkElement != null) + { + FrameworkElement.Loaded += (sender, args) => + { + // If the view is a layout (stacklayout, grid, etc) we need to trigger a layout pass + // with all the controls in a consistent native state (i.e., loaded) so they'll actually + // have Bounds set + (_view as Layout)?.ForceLayout(); + InvalidateMeasure(); + }; + } } protected override Windows.Foundation.Size ArrangeOverride(Windows.Foundation.Size finalSize) @@ -65,18 +76,15 @@ namespace Xamarin.Forms.Platform.WinRT Layout.LayoutChildIntoBoundingRegion(_view, new Rectangle(0, 0, finalSize.Width, finalSize.Height)); _view.IsInNativeLayout = false; - var content = Content as FrameworkElement; - content.Arrange(new Rect(_view.X, _view.Y, _view.Width, _view.Height)); + FrameworkElement?.Arrange(new Rect(_view.X, _view.Y, _view.Width, _view.Height)); return finalSize; } protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Size availableSize) { - var content = Content as FrameworkElement; - content?.Measure(availableSize); Size request = _view.Measure(availableSize.Width, availableSize.Height, MeasureFlags.IncludeMargins).Request; - - var result = new Windows.Foundation.Size(); + + Windows.Foundation.Size result; if (_view.HorizontalOptions.Alignment == LayoutAlignment.Fill && !double.IsInfinity(availableSize.Width) && availableSize.Width != 0) { result = new Windows.Foundation.Size(availableSize.Width, request.Height); @@ -86,7 +94,10 @@ namespace Xamarin.Forms.Platform.WinRT result = new Windows.Foundation.Size(request.Width, request.Height); } - _view.Layout(new Rectangle(0, 0, result.Width, result.Width)); + _view.Layout(new Rectangle(0, 0, result.Width, result.Height)); + + FrameworkElement?.Measure(availableSize); + return result; } |