Связывание с 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>
Содержимое страницы заменяет предъявитель содержимого в шаблоне. Выглядит проще, чем базовая страница.