【问题标题】:Binding with BasePage in Xamarin Forms在 Xamarin 表单中与 BasePage 绑定
【发布时间】:2018-02-23 13:10:01
【问题描述】:

我正在使用 FreshMVVM 框架实现一个 Xamarin 应用程序,我想使用 BasePage 在页面之间共享一些代码。 问题是,当我需要在 MainPage.xaml 中绑定一些属性时,我必须以这种方式指定 Source 以使其工作:Text="{Binding Title, Source={ x:参考主页面}}"。否则没有 Source 绑定不起作用。 好的,我明白了,但这是正确的方法吗?有没有其他方法可以达到同样的效果?当我在页面中有大量绑定时怎么办?例如,是否可以在上层“设置” Source,因为在我看来,为每个 Binding 设置相同的 Source 非常烦人。

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();
		}
	}

【问题讨论】:

  • 您使用的是 MVVM 框架吗?如果没有,我建议您研究一下,因为它可以大大简化您的绑定体验。
  • 只有BindingContext支持属性值继承,Source不支持
  • @StevenThewissen 其实我用的是FreshMVVM,但似乎有同样的问题。

标签: binding xamarin.forms freshmvvm binding-context


【解决方案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>

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

【讨论】:

  • 是的,您提出的是一个可行的解决方案,事实上,目前我正在通过使用 ControlTemplate 来逃避这个问题。我不喜欢这个解决方案的一点是相对于 BasePage 方法的较小的灵活性。据我所知,将参数传递给 ControlTemplate 的唯一方法是从 ViewModel 属性绑定,而在某些情况下,我想从 Xaml 页面设置参数,并且使用 BindableProperty 我可以做到。
猜你喜欢
  • 2020-02-29
  • 1970-01-01
  • 2016-10-10
  • 2018-12-16
  • 2018-03-13
  • 2015-11-05
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
相关资源
最近更新 更多