2017-09-14 162 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