Связывание с BasePage в формах Xamarin

Я реализую приложение Xamarin с фреймворком FreshMVVM, и я хочу использовать BasePage для совместного использования некоторого кода среди страниц. Проблема в том, что когда мне нужно связать некоторые свойства в MainPage.xaml, я должен указать источник таким образом, чтобы он работал: Text = "{Binding Title, Source = {x: Reference mainPage}}". В противном случае без привязки источника не работает. Хорошо, я понимаю, но это правильный путь? Есть ли другой способ добиться того же результата? А как насчет того, когда у меня много привязок на странице? Например, возможно ли "установить" источник на верхнем уровне, потому что, на мой взгляд, установка одного и того же источника для каждой привязки очень раздражает.

BasePage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TestXamarin.BasePage"
             x:Name="basePage">
    <ContentView>
        <StackLayout Orientation="Vertical">
            <Label Text="HEADER" FontSize="Large"/>
            <Label Text="{Binding Text, Source={x:Reference basePage}}" FontSize="Large"/>
            <ContentPresenter BindingContext="{Binding Parent.BindingContext}" 
                              Content="{Binding PageContent, Source={x:Reference basePage}}" />
        </StackLayout>
    </ContentView>
</ContentPage>

BasePage.xaml.cs

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace TestXamarin
{
 [XamlCompilation(XamlCompilationOptions.Compile)]
 public partial class BasePage : ContentPage
 {
  public static readonly BindableProperty TextProperty = BindableProperty.Create(
      nameof(Text),
      typeof(string),
      typeof(BasePage));

  public string Text
  {
   get { return (string)GetValue(TextProperty); }
   set { SetValue(TextProperty, value); }
  }

  public static readonly BindableProperty PageContentProperty = BindableProperty.Create(
      nameof(PageContent),
      typeof(object),
      typeof(BasePage));

  public object PageContent
  {
    get { return GetValue(PageContentProperty); }
    set { SetValue(PageContentProperty, value); }
  }

  public BasePage()
  {
   InitializeComponent();
  }
 }
}

MainPage.xaml

<local:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:local="clr-namespace:TestXamarin"
                x:Class="TestXamarin.MainPage"
                Text="FROM MAIN PAGE"
                x:Name="mainPage">
    <local:BasePage.PageContent>
        <StackLayout>
            <Label Text="Body" FontSize="Large"/>
            <Label Text="{Binding Title, Source={x:Reference mainPage}}" FontSize="Large"/>
        </StackLayout>
    </local:BasePage.PageContent>
</local:BasePage>

MainPage.xaml.cs

public partial class MainPage : BasePage
 {
  public MainPage()
  {
   Title = "MAIN PAGE";

   InitializeComponent();
  }
 }

1 ответ

Еще один способ добиться того, что вы пытаетесь сделать, - использовать шаблоны управления.

Здесь я определил шаблон в App.xaml

<ControlTemplate x:Key="ActivityIndicatorTemplate">
    <Grid>
        <ContentPresenter />
        <StackLayout Style="{StaticResource BlockingPanel}"
                     IsVisible="{TemplateBinding BindingContext.IsBusy}">
            <ActivityIndicator Style="{StaticResource ActivityIndicatorStyle}"
                               IsVisible="{TemplateBinding BindingContext.IsBusy}"
                               IsRunning="{TemplateBinding BindingContext.IsBusy}" />
        </StackLayout>
    </Grid>
</ControlTemplate>

Обратите внимание на предъявителя контента и TemplateBinding.

Я использую это на такой странице.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Test.MyTestPage"
             ControlTemplate="{StaticResource ActivityIndicatorTemplate}"
             Title="{Binding Title}">

    <Grid>
    ...
    </Grid>
</ContentPage>

Содержимое страницы заменяет предъявитель содержимого в шаблоне. Выглядит проще, чем базовая страница.

Другие вопросы по тегам