[UWP] Fix TitleView Width and MDP rendering quirks (#3987)
* [UWP] Fix TitleView Width and MDP rendering quirks * [UWP] fix load timing for pushed pages and titleview * [UWP] move renderer check * [UWP] remove re-measure until 4116 fixed - fixes #3828 - fixes #3834
This commit is contained in:
Родитель
2eee6d1eff
Коммит
71429f7cdd
|
@ -9,7 +9,6 @@
|
|||
<Label Text="I can be a subtitle" />
|
||||
</StackLayout>
|
||||
</NavigationPage.TitleView>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout BackgroundColor="Pink">
|
||||
<Button Clicked="masterDetailsPage_Clicked" Text="Master Details Page"></Button>
|
||||
|
@ -22,6 +21,7 @@
|
|||
<Button Clicked="toggleSecondaryToolBarItem_Clicked" Text="Toggle Secondary Tool Bar Item" ></Button>
|
||||
<Button Clicked="toggleLargeTitles_Clicked" Text="Toggle Large Titles" ></Button>
|
||||
<Button Clicked="changeTitleView_Clicked" Text="Toggle Different Title Views"></Button>
|
||||
<Button Clicked="swapDetails_Page" Text="Swap Details Page"></Button>
|
||||
<Button x:Name="btnToggleBackButtonTitle" Clicked="toggleBackButtonText_Clicked" Text="Toggle Back Button Title Text"></Button>
|
||||
<Button Clicked="backToGallery_Clicked" Text="Back to Gallery"></Button>
|
||||
</StackLayout>
|
||||
|
|
|
@ -24,12 +24,13 @@ namespace Xamarin.Forms.Controls.GalleryPages
|
|||
}
|
||||
}
|
||||
|
||||
NavigationPage CreateNavigationPage()
|
||||
static NavigationPage CreateNavigationPage()
|
||||
{
|
||||
return new NavigationPage(new TitleView(false) { Title = "Nav Title" });
|
||||
var page = new TitleView(false) { Title = "Nav Title" };
|
||||
return new NavigationPage(page);
|
||||
}
|
||||
|
||||
public Page GetPage()
|
||||
public static Page GetPage()
|
||||
{
|
||||
return new MasterDetailPage()
|
||||
{
|
||||
|
@ -38,6 +39,14 @@ namespace Xamarin.Forms.Controls.GalleryPages
|
|||
};
|
||||
}
|
||||
|
||||
void swapDetails_Page(object sender, EventArgs e)
|
||||
{
|
||||
if (App.Current.MainPage is MasterDetailPage mdp)
|
||||
{
|
||||
mdp.Detail = CreateNavigationPage();
|
||||
}
|
||||
}
|
||||
|
||||
void masterDetailsPage_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
App.Current.MainPage =
|
||||
|
@ -125,12 +134,12 @@ namespace Xamarin.Forms.Controls.GalleryPages
|
|||
Navigation.PushAsync(page);
|
||||
}
|
||||
|
||||
View createSearchBarView()
|
||||
static View createSearchBarView()
|
||||
{
|
||||
return new SearchBar { BackgroundColor = Color.Cornsilk, HorizontalOptions = LayoutOptions.FillAndExpand, Margin = new Thickness(10, 0) };
|
||||
}
|
||||
|
||||
View createGrid()
|
||||
static View createGrid()
|
||||
{
|
||||
var grid = new Grid
|
||||
{
|
||||
|
@ -157,13 +166,18 @@ namespace Xamarin.Forms.Controls.GalleryPages
|
|||
|
||||
void titleIcon_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var titleIcon = NavigationPage.GetTitleIcon(this);
|
||||
toggleTitleIcon(this);
|
||||
|
||||
}
|
||||
|
||||
static void toggleTitleIcon(Page page)
|
||||
{
|
||||
var titleIcon = NavigationPage.GetTitleIcon(page);
|
||||
|
||||
if (titleIcon == null)
|
||||
NavigationPage.SetTitleIcon(this, "coffee.png");
|
||||
NavigationPage.SetTitleIcon(page, "coffee.png");
|
||||
else
|
||||
NavigationPage.SetTitleIcon(this, null);
|
||||
|
||||
NavigationPage.SetTitleIcon(page, null);
|
||||
}
|
||||
|
||||
void masterDetailsPageIcon_Clicked(object sender, EventArgs e)
|
||||
|
@ -188,9 +202,10 @@ namespace Xamarin.Forms.Controls.GalleryPages
|
|||
(App.Current as App).Reset();
|
||||
}
|
||||
|
||||
void toggleToolBarItem_Clicked(object sender, EventArgs e)
|
||||
void toggleToolBarItem_Clicked(object sender, EventArgs e) => toggleToolBarItem(Navigation.NavigationStack.Last());
|
||||
|
||||
static void toggleToolBarItem(Page page)
|
||||
{
|
||||
var page = Navigation.NavigationStack.Last();
|
||||
var items = page.ToolbarItems.Where(x => x.Order == ToolbarItemOrder.Primary).ToList();
|
||||
|
||||
if (items.Any())
|
||||
|
@ -215,14 +230,19 @@ namespace Xamarin.Forms.Controls.GalleryPages
|
|||
|
||||
void changeTitleView_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var currentView = NavigationPage.GetTitleView(Navigation.NavigationStack.Last());
|
||||
changeTitleView(Navigation.NavigationStack.Last());
|
||||
}
|
||||
|
||||
static void changeTitleView(Page page)
|
||||
{
|
||||
var currentView = NavigationPage.GetTitleView(page);
|
||||
|
||||
if (currentView is Grid)
|
||||
NavigationPage.SetTitleView(Navigation.NavigationStack.Last(), createSearchBarView());
|
||||
NavigationPage.SetTitleView(page, createSearchBarView());
|
||||
else if (currentView is SearchBar)
|
||||
NavigationPage.SetTitleView(Navigation.NavigationStack.Last(), null);
|
||||
NavigationPage.SetTitleView(page, null);
|
||||
else
|
||||
NavigationPage.SetTitleView(Navigation.NavigationStack.Last(), createGrid());
|
||||
NavigationPage.SetTitleView(page, createGrid());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
internal interface ITitleViewRendererController
|
||||
{
|
||||
View TitleView { get; }
|
||||
FrameworkElement TitleViewPresenter { get; }
|
||||
Visibility TitleViewVisibility { get; set; }
|
||||
CommandBar CommandBar { get; }
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ using WImageSource = Windows.UI.Xaml.Media.ImageSource;
|
|||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
public class MasterDetailControl : Control, IToolbarProvider
|
||||
public class MasterDetailControl : Control, IToolbarProvider, ITitleViewRendererController
|
||||
{
|
||||
public static readonly DependencyProperty MasterProperty = DependencyProperty.Register("Master", typeof(FrameworkElement), typeof(MasterDetailControl),
|
||||
new PropertyMetadata(default(FrameworkElement)));
|
||||
|
@ -75,6 +75,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
SplitView _split;
|
||||
ToolbarPlacement _toolbarPlacement;
|
||||
FrameworkElement _titleViewPresenter;
|
||||
TitleViewManager _titleViewManager;
|
||||
|
||||
public MasterDetailControl()
|
||||
{
|
||||
|
@ -296,6 +297,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
if (_commandBarTcs != null)
|
||||
_commandBarTcs.SetResult(_commandBar);
|
||||
|
||||
_titleViewManager = new TitleViewManager(this);
|
||||
}
|
||||
|
||||
static void OnShouldShowSplitModeChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
|
@ -315,7 +318,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
static void OnTitleViewPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
((MasterDetailControl)dependencyObject).UpdateTitleViewPresenter();
|
||||
((MasterDetailControl)dependencyObject)._titleViewManager?.OnTitleViewPropertyChanged();
|
||||
}
|
||||
|
||||
void OnToggleClicked(object sender, RoutedEventArgs args)
|
||||
|
@ -323,14 +326,6 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
IsPaneOpen = !IsPaneOpen;
|
||||
}
|
||||
|
||||
void OnTitleViewPresenterLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DetailTitleView == null || _titleViewPresenter == null || _commandBar == null)
|
||||
return;
|
||||
|
||||
_titleViewPresenter.Width = _commandBar.ActualWidth;
|
||||
}
|
||||
|
||||
void UpdateMode()
|
||||
{
|
||||
if (_split == null)
|
||||
|
@ -366,22 +361,15 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
_firstLoad = true;
|
||||
}
|
||||
|
||||
void UpdateTitleViewPresenter()
|
||||
View ITitleViewRendererController.TitleView => DetailTitleView;
|
||||
FrameworkElement ITitleViewRendererController.TitleViewPresenter => _titleViewPresenter;
|
||||
Visibility ITitleViewRendererController.TitleViewVisibility
|
||||
{
|
||||
if (DetailTitleView == null)
|
||||
{
|
||||
DetailTitleViewVisibility = Visibility.Collapsed;
|
||||
get => DetailTitleViewVisibility;
|
||||
set => DetailTitleViewVisibility = value;
|
||||
}
|
||||
|
||||
if (_titleViewPresenter != null)
|
||||
_titleViewPresenter.Loaded -= OnTitleViewPresenterLoaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailTitleViewVisibility = Visibility.Visible;
|
||||
CommandBar ITitleViewRendererController.CommandBar { get => _commandBar; }
|
||||
|
||||
if (_titleViewPresenter != null)
|
||||
_titleViewPresenter.Loaded += OnTitleViewPresenterLoaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,6 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
{
|
||||
UpdateDetailTitle();
|
||||
UpdateDetailTitleIcon();
|
||||
UpdateDetailTitleView();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,7 +312,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
if (_detail == null)
|
||||
return;
|
||||
|
||||
Control.DetailTitle = (_detail as NavigationPage)?.CurrentPage?.Title ?? _detail.Title ?? Element?.Title;
|
||||
Control.DetailTitle = GetCurrentPage().Title ?? Element?.Title;
|
||||
(this as ITitleProvider).ShowTitle = !string.IsNullOrEmpty(Control.DetailTitle);
|
||||
}
|
||||
|
||||
|
@ -322,7 +321,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
if (_detail == null)
|
||||
return;
|
||||
|
||||
Control.DetailTitleIcon = await NavigationPage.GetTitleIcon(_detail).ToWindowsImageSource();
|
||||
Control.DetailTitleIcon = await NavigationPage.GetTitleIcon(GetCurrentPage()).ToWindowsImageSource();
|
||||
Control.InvalidateMeasure();
|
||||
}
|
||||
|
||||
|
@ -331,7 +330,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
if (_detail == null)
|
||||
return;
|
||||
|
||||
Control.DetailTitleView = NavigationPage.GetTitleView(_detail) as View;
|
||||
Control.DetailTitleView = NavigationPage.GetTitleView(GetCurrentPage()) as View;
|
||||
Control.InvalidateMeasure();
|
||||
}
|
||||
|
||||
|
@ -409,5 +408,13 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
element.SetBinding(Windows.UI.Xaml.Controls.Control.ForegroundProperty,
|
||||
new Windows.UI.Xaml.Data.Binding { Path = new PropertyPath("Control.ToolbarForeground"), Source = this, RelativeSource = new RelativeSource { Mode = RelativeSourceMode.TemplatedParent } });
|
||||
}
|
||||
|
||||
Page GetCurrentPage()
|
||||
{
|
||||
if (_detail is NavigationPage page)
|
||||
return page.CurrentPage;
|
||||
|
||||
return _detail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
VisualElementTracker<Page, PageControl> _tracker;
|
||||
EntranceThemeTransition _transition;
|
||||
Platform _platform;
|
||||
bool _parentsLookedUp = false;
|
||||
|
||||
Platform Platform => _platform ?? (_platform = Platform.Current);
|
||||
|
||||
|
@ -308,12 +309,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
_parentMasterDetailPage.PropertyChanged += MultiPagePropertyChanged;
|
||||
|
||||
UpdateShowTitle();
|
||||
|
||||
UpdateTitleOnParents();
|
||||
|
||||
UpdateTitleIcon();
|
||||
|
||||
UpdateTitleView();
|
||||
_parentsLookedUp = true;
|
||||
}
|
||||
|
||||
void MultiPagePropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
@ -383,6 +380,12 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
Element.SendAppearing();
|
||||
UpdateBackButton();
|
||||
UpdateTitleOnParents();
|
||||
|
||||
if (_parentMasterDetailPage != null)
|
||||
{
|
||||
UpdateTitleView();
|
||||
UpdateTitleIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void OnNativeSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
|
@ -466,7 +469,6 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
UpdateTitleVisible();
|
||||
UpdateTitleOnParents();
|
||||
UpdateTitleIcon();
|
||||
UpdateTitleView();
|
||||
|
||||
if (isAnimated && _transition == null)
|
||||
|
@ -549,13 +551,21 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
void UpdateTitleView()
|
||||
{
|
||||
if (_currentPage == null)
|
||||
// if the life cycle hasn't reached the point where _parentMasterDetailPage gets wired up then
|
||||
// don't update the title view
|
||||
if (_currentPage == null || !_parentsLookedUp)
|
||||
return;
|
||||
|
||||
// If the container TitleView gets initialized before the MDP TitleView it causes the
|
||||
// MDP TitleView to not render correctly
|
||||
if (_parentMasterDetailPage != null)
|
||||
{
|
||||
if (Platform.GetRenderer(_parentMasterDetailPage) is ITitleViewProvider parent)
|
||||
parent.TitleView = TitleView;
|
||||
}
|
||||
else if (_parentMasterDetailPage == null)
|
||||
_container.TitleView = TitleView;
|
||||
|
||||
if (_parentMasterDetailPage != null && Platform.GetRenderer(_parentMasterDetailPage) is ITitleViewProvider parent)
|
||||
parent.TitleView = TitleView;
|
||||
}
|
||||
|
||||
SystemNavigationManager _navManager;
|
||||
|
|
|
@ -7,7 +7,7 @@ using WImageSource = Windows.UI.Xaml.Media.ImageSource;
|
|||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
public sealed class PageControl : ContentControl, IToolbarProvider
|
||||
public sealed class PageControl : ContentControl, IToolbarProvider, ITitleViewRendererController
|
||||
{
|
||||
public static readonly DependencyProperty TitleVisibilityProperty = DependencyProperty.Register(nameof(TitleVisibility), typeof(Visibility), typeof(PageControl), new PropertyMetadata(Visibility.Visible));
|
||||
|
||||
|
@ -55,6 +55,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
TaskCompletionSource<CommandBar> _commandBarTcs;
|
||||
Windows.UI.Xaml.Controls.ContentPresenter _presenter;
|
||||
TitleViewManager _titleViewManager;
|
||||
|
||||
public PageControl()
|
||||
{
|
||||
|
@ -123,6 +124,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
set { SetValue(TitleInsetProperty, value); }
|
||||
}
|
||||
|
||||
FrameworkElement ITitleViewRendererController.TitleViewPresenter => _titleViewPresenter;
|
||||
CommandBar ITitleViewRendererController.CommandBar => _commandBar;
|
||||
|
||||
Task<CommandBar> IToolbarProvider.GetCommandBarAsync()
|
||||
{
|
||||
if (_commandBar != null)
|
||||
|
@ -143,6 +147,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
_commandBar = GetTemplateChild("CommandBar") as CommandBar;
|
||||
|
||||
_titleViewManager = new TitleViewManager(this);
|
||||
|
||||
_toolbarPlacementHelper.Initialize(_commandBar, () => ToolbarPlacement, GetTemplateChild);
|
||||
|
||||
|
@ -152,33 +157,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
static void OnTitleViewPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
((PageControl)dependencyObject).UpdateTitleViewPresenter();
|
||||
}
|
||||
|
||||
void OnTitleViewPresenterLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (TitleView == null || _titleViewPresenter == null || _commandBar == null)
|
||||
return;
|
||||
|
||||
_titleViewPresenter.Width = _commandBar.ActualWidth;
|
||||
}
|
||||
|
||||
void UpdateTitleViewPresenter()
|
||||
{
|
||||
if (TitleView == null)
|
||||
{
|
||||
TitleViewVisibility = Visibility.Collapsed;
|
||||
|
||||
if (_titleViewPresenter != null)
|
||||
_titleViewPresenter.Loaded -= OnTitleViewPresenterLoaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
TitleViewVisibility = Visibility.Visible;
|
||||
|
||||
if (_titleViewPresenter != null)
|
||||
_titleViewPresenter.Loaded += OnTitleViewPresenterLoaded;
|
||||
}
|
||||
((PageControl)dependencyObject)._titleViewManager?.OnTitleViewPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
{
|
||||
internal class TitleViewManager
|
||||
{
|
||||
readonly ITitleViewRendererController _titleViewRendererController;
|
||||
|
||||
View TitleView => _titleViewRendererController.TitleView;
|
||||
CommandBar CommandBar => _titleViewRendererController.CommandBar;
|
||||
FrameworkElement TitleViewPresenter => _titleViewRendererController.TitleViewPresenter;
|
||||
|
||||
public TitleViewManager(ITitleViewRendererController titleViewRendererController)
|
||||
{
|
||||
_titleViewRendererController = titleViewRendererController;
|
||||
_titleViewRendererController.TitleViewPresenter.Loaded += OnTitleViewPresenterLoaded;
|
||||
|
||||
// Uncomment once https://github.com/xamarin/Xamarin.Forms/issues/4116 is fixed
|
||||
// CommandBar.LayoutUpdated += commandLayoutUpdated;
|
||||
// CommandBar.Unloaded += commandBarUnloaded;
|
||||
}
|
||||
|
||||
internal void OnTitleViewPropertyChanged()
|
||||
{
|
||||
UpdateTitleViewWidth();
|
||||
}
|
||||
|
||||
void OnTitleViewPresenterLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UpdateTitleViewWidth();
|
||||
TitleViewPresenter.Loaded -= OnTitleViewPresenterLoaded;
|
||||
}
|
||||
|
||||
void commandBarUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
CommandBar.LayoutUpdated -= commandLayoutUpdated;
|
||||
CommandBar.Unloaded -= commandBarUnloaded;
|
||||
}
|
||||
|
||||
void commandLayoutUpdated(object sender, object e)
|
||||
{
|
||||
UpdateTitleViewWidth();
|
||||
}
|
||||
|
||||
void UpdateTitleViewWidth()
|
||||
{
|
||||
if (TitleView == null || TitleViewPresenter == null || CommandBar == null)
|
||||
return;
|
||||
|
||||
if (CommandBar.ActualWidth <= 0) return;
|
||||
|
||||
double buttonWidth = 0;
|
||||
foreach (var item in CommandBar.GetDescendantsByName<Windows.UI.Xaml.Controls.Button>("MoreButton"))
|
||||
if (item.Visibility == Visibility.Visible)
|
||||
buttonWidth += item.ActualWidth;
|
||||
|
||||
if (!CommandBar.IsDynamicOverflowEnabled)
|
||||
foreach (var item in CommandBar.GetDescendantsByName<ItemsControl>("PrimaryItemsControl"))
|
||||
buttonWidth += item.ActualWidth;
|
||||
|
||||
TitleViewPresenter.Width = CommandBar.ActualWidth - buttonWidth;
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
void UpdateVisibility()
|
||||
{
|
||||
if (TitleView == null)
|
||||
_titleViewRendererController.TitleViewVisibility = Visibility.Collapsed;
|
||||
else
|
||||
_titleViewRendererController.TitleViewVisibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@
|
|||
<Compile Include="ITitleIconProvider.cs" />
|
||||
<Compile Include="ITitleProvider.cs" />
|
||||
<Compile Include="ITitleViewProvider.cs" />
|
||||
<Compile Include="ITitleViewRendererController.cs" />
|
||||
<Compile Include="IToolbarProvider.cs" />
|
||||
<Compile Include="NativeBindingExtensions.cs" />
|
||||
<Compile Include="NativeEventWrapper.cs" />
|
||||
|
@ -70,6 +71,7 @@
|
|||
<Compile Include="PlatformConfigurationExtensions.cs" />
|
||||
<Compile Include="PlatformEffect.cs" />
|
||||
<Compile Include="TextBlockExtensions.cs" />
|
||||
<Compile Include="TitleViewManager.cs" />
|
||||
<Compile Include="UriImageSourceHandler.cs" />
|
||||
<Compile Include="ViewExtensions.cs" />
|
||||
<Compile Include="LayoutExtensions.cs" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче