2017-09-14 120 views
0

我正在实施FreshMVVM框架的Xamarin应用程序,并且我想使用BasePage在Pages之间共享一些代码。 问题是,当我需要在MainPage.xaml中绑定一些属性时,我必须指定以使其工作:Text =“{Binding Title,Source = {x:Reference mainPage}} “。否则无来源绑定不起作用。 好吧,我明白了,但这是正确的方式吗?有另一种方法可以达到相同的结果吗?当我在页面中有足够的绑定时怎么办?例如,是否有可能将Source设置为较高级别,因为在我看来,为每个Binding设置相同的Source非常烦人。在Xamarin Forms中与BasePage绑定

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 
 
{ 
 
\t [XamlCompilation(XamlCompilationOptions.Compile)] 
 
\t public partial class BasePage : ContentPage 
 
\t { 
 
\t \t public static readonly BindableProperty TextProperty = BindableProperty.Create(
 
\t \t \t nameof(Text), 
 
\t \t \t typeof(string), 
 
\t \t \t typeof(BasePage)); 
 

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

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

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

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

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 
 
\t { 
 
\t \t public MainPage() 
 
\t \t { 
 
\t \t \t Title = "MAIN PAGE"; 
 

 
\t \t \t InitializeComponent(); 
 
\t \t } 
 
\t }

+0

您使用的是MVVM框架吗?如果没有,我会建议你看看它,因为它可以大大简化你的约束力经验。 –

+1

只有'BindingContext'支持属性值继承,而不是'Source' – Ada

+0

@StevenThewissen其实我正在使用FreshMVVM,但它似乎有同样的问题。 – user2297037

回答

3

另一种方式来实现你所要做的是,与对照模板。

在这里,我已经在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> 

页面内容替换模板中的内容展示器。看起来比基本页面更简单。

+0

是的,你提出的是一个工作解决方案,实际上我现在通过使用ControlTemplate来逃避这个问题。 我不喜欢这个解决方案是针对BasePage方法的小灵活性。据我所知,将参数传递给ControlTemplate的唯一方法是从ViewModel属性绑定,而不是在某些情况下,我想从Xaml Page和使用BindableProperty设置参数。 – user2297037