xamarin формирует подзаголовок приложения
У меня есть приложение Xamarin Forms, и я хочу разместить стандартный (под) заголовок на каждой странице. Подзаголовок будет содержать метку, которая будет меняться для каждой страницы, и дополнительную кнопку "Назад", и будет находиться чуть ниже заголовка приложения, который содержит гамбургер меню и имя приложения.
Первоначально я создал "HeaderPage", который содержал макет для стандартных элементов управления, и все мои страницы унаследованы от этой страницы. Я "спрятал" ContentPage.Content, чтобы страницы, унаследованные от HeaderPage, могли просто установить Content = для установки содержимого HeaderPage
private ContentView _headerPageContent;
public new View Content
{
set { _headerPageContent.Content = value; }
}
и дочерняя страница просто должна была установить текст:
HeaderLabel = "Contact Us";
Это прекрасно работало до Forms 2.1, где была удалена возможность маскировать ContentPage.Content.
В то время рекомендовалось использовать ContentPage с ControlTemplate с заголовком. Я исследовал этот путь, как и один из моих коллег, и мы оба отступили из-за сложности и дублирования кода, накладывающего привязку на каждую страницу.
Я думал о создании заголовка или о том, что нужно сделать, чтобы сделать его контролем.
Сейчас я выбрал простой путь и переименовал переменную "Content" в "HeaderPage Content", чтобы все страницы, которые наследуются от страницы Header, устанавливали HeaderPage Content вместо Content.
Кто-нибудь еще делал что-то подобное? Что ты нашел?
1 ответ
Я столкнулся с той же проблемой в своем приложении и нашел решение, подобное вам.
Создать PageBase
класс, который наследуется от Xamarin.Forms.Page
- In that class create a `property` named `PageContent` typeof `View`.(Content will be there)
- (optional)Override the default attribute for class: `[Xamarin.Forms.ContentProperty("PageContent")]` so you will not be have to annotate into xaml each time.
- Override `OnParentSet` method like you want to style the page.
Образец класса и использования
//PageBase Class
namespace Test.Views.Base
{
[Xamarin.Forms.ContentProperty("PageContent")]
public class PageBase: Xamarin.Foorms.Page
{
private Grid _mainLayout;
private Label _headerLabel;
private Label _footerLabel;
public View PageContent{get;set;}
public string HeaderText{get;set;} // you can make this property bindable
public string FooterText{get;set;} // you can make this property bindable
public PageBase():base()
{
_mainLayout = new Grid();
_mainLayout.RowDefinitions.Add(new RowDefinition(){Height= new GridLenght(50, GridUnitType.Absolute)}); //Header
_mainLayout.RowDefinitions.Add(new RowDefinition(){Height= new GridLenght(1, GridUnitType.Star)}); //Content
_mainLayout.RowDefinitions.Add(new RowDefinition(){Height= new GridLenght(50, GridUnitType.Absolute)}); //Footer
_headerLabel = new Label();
_footerLabel = new Label();
_mainLayout.Children.Add(_headerLabel);
_mainLayout.Children.Add(_footerLabel);
Grid.SetRow(_footerLabel,2);
}
protected override void OnParentSet()
{
base.OnParentSet();
if(PageContent != null)
{
_mainLayout.Children.Add(PageContent);
Grid.SetRow(PageContent,1);
this.Content= _mainLayout;
}
_headerLabel.Text = HeaderText;
_footerLabel.Text = FooterText;
}
}
}
Вот Ксамл
<?xml version="1.0" encoding="utf-8" ?>
<local:PageBase xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Test.Views.Base;assembly=Test"
xmlns:cell="clr-namespace:Test.Views;assembly=Test"
x:Class="Test.Views.TestPage"
HeaderText="Page Header"
FooterText="Page Footer"
>
<local:PageBase.PageContent>
<!-- Here Goes Page Content -->
</local:PageBase.PageContent>
</local:PageBase>