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
This commit is contained in:
E.Z. Hart 2016-08-30 12:12:27 -06:00 коммит произвёл Jason Smith
Родитель 0bc22bda64
Коммит 1b7250167f
6 изменённых файлов: 249 добавлений и 14 удалений

Просмотреть файл

@ -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;
}
}
}
}

Просмотреть файл

@ -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" />

Просмотреть файл

@ -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())

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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:

Просмотреть файл

@ -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;
}