如何在Xamarin表单中使用ControlTemplate进行替代绑定 [英] How to do alternative binding with ControlTemplate in Xamarin Forms

查看:68
本文介绍了如何在Xamarin表单中使用ControlTemplate进行替代绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ControlTemplate 在Android和iOS上具有一致的导航栏

I am using ControlTemplate have consistent Navigation Bar accross Android and iOS

<ControlTemplate x:Key="NavBarTemplate">
    <StackLayout>
        <StackLayout Orientation="Horizontal" 
            VerticalOptions="CenterAndExpand" 
            IsVisible="{TemplateBinding BindingContext.IsBackButtonVisible, Mode=TwoWay}">
            <Label Text="&lt;" 
                FontSize="Large" 
                FontAttributes="Bold" 
                HorizontalTextAlignment="Center" 
                VerticalOptions="FillAndExpand" 
                VerticalTextAlignment="Center" 
                Margin="20,0,0,0" />
            <Label TextColor="{StaticResource DarkGrey}" 
                HorizontalOptions="StartAndExpand" 
                HorizontalTextAlignment="Center" 
                VerticalOptions="FillAndExpand" 
                VerticalTextAlignment="Center" 
                FontSize="Small" 
                Text="Back" />
            <StackLayout.GestureRecognizers>
                <TapGestureRecognizer Command="{TemplateBinding BindingContext.NavigateBackCommand}" />
            </StackLayout.GestureRecognizers>
        </StackLayout>
        <Image Source="logo.png" 
            VerticalOptions="Center" />
    </StackLayout>
</ControlTemplate>

为了动态显示后退按钮,我在 BasePage.cs

In order to dynamically display back button I have added below code in OnAppearing of BasePage.cs

protected override void OnAppearing () 
{
    base.OnAppearing ();

    if (BindingContext is BaseViewModel viewmodel) 
    {
        if(Application.Current.MainPage as NavigationPage nav)
        {

            if(nav.Navigation.NavigationStack.Count >1 )
            {
                viewmodel.IsBackButtonVisible = true;
            }else
            {
                viewmodel.IsBackButtonVisible = false;
            }
            //dirty coding force to false
            if (!this.IsBackButtonVisible) //refers to local BindableProperty
            {
                viewmodel.IsBackButtonVisible = false;
            }
        }else //no viewmodel found just use localbinding 
        {
            BindingContext = this;
        }
    }
}

因此,在某些页面中,即使 NavigationStack 是> 1

So in some pages I want to enforce Back button off even though NavigationStack is > 1

现在,我通过在BasePage中将具有相同名称 IsBackButtonVisible

Right now I am achieving based on Dirty coding above by having BindableProperty in the BasePage with same name IsBackButtonVisible

我的问题是,有没有一种方法可以为 ControlTemplate 做替代绑定,我知道正常的Binding有FallBackValue和Default(它们只是没有绑定的值),但我不想这么做对其进行编码,似乎TemplateBinding不支持那些功能(智能不会显示这些选项)

My question is , is there a way to do alternative binding for ControlTemplate , I know there is FallBackValue and Default for normal Binding( which are just values not binding ofcourse) but I dont want to hard code it and seems TemplateBinding doesnt support those(intellisence wont show these options)

我想做的是将 BasePage 中的 BindableProperty 重命名为 ForceNoBackButton ,并使导航栏尽管具有ViewModel绑定也不可见.

What I want to do is rename BindableProperty in BasePage to ForceNoBackButton and make navigation bar invisible despite of ViewModel binding.

有什么方法可以根据条件在 TemplateBinding 中进行替代绑定.

Is there any way to do alternative binding in TemplateBinding based on conditions..

  1. 如果BindingContext是BaseViewModel类型,则使用属性 IsBackButtonVisible

否则,如果页面 BindingContext 是此页面还是 BaseViewModel 之外的其他内容,则回退到 BasePage 本地 BindableProperty ,即 ForceNoBackButton

Else if page BindingContext is this page or something other than BaseViewModel then fallback to BasePage local BindableProperty i.e ForceNoBackButton

我可以使用BindableProperty的propertychanged事件处理程序来做到这一点吗?如果是,如何.我知道如果可视元素位于当前XAML中,该怎么做,不知道如何针对 TemplatedView

Can I do it with propertychanged event handler of BindableProperty ? If yes, how. I know how to do it if the visual element is in the current XAML, dont know how to do it for TemplatedView

推荐答案

您可以在 BasePage 上创建两个可绑定属性 IsBackButtonVisible ForceNoBackButton .

You can create two bindable properties IsBackButtonVisible and ForceNoBackButton on BasePage.

public static readonly BindableProperty ForceNoBackButtonProperty =
    BindableProperty.Create(
    "ForceNoBackButton", typeof(bool), typeof(BasePage),
    defaultValue: default(bool));

public static readonly BindableProperty IsBackButtonVisibleProperty =
    BindableProperty.Create(
    "IsBackButtonVisible", typeof(bool), typeof(BasePage),
    defaultValue: default(bool));

并更新您的控件模板以仅使用 IsBackButtonVisible

And update your control-template to simply use IsBackButtonVisible

<ControlTemplate x:Key="NavBarTemplate">
    ...
    <StackLayout Orientation="Horizontal" 
        ..
        IsVisible="{TemplateBinding IsBackButtonVisible}">

同时修改如下的 OnAppearing()方法:

protected override void OnAppearing()
{
    ..
    if (nav.Navigation.NavigationStack.Count > 1)
    {
        IsBackButtonVisible = !ForceNoBackButton;
    }
    else
    {
        IsBackButtonVisible = false;
    }

要使关联的视图模型与此属性保持同步-您可以在 BasePage.xaml 上设置绑定, BasePage()中添加以下行构造函数以编程方式设置此绑定.

To keep the associated viewmodel in sync with this property - you can either set binding on BasePage.xaml, or add following line in BasePage() constructor to set this binding programmatically.

public BasePage()
{
    InitializeComponent();
    SetBinding(IsBackButtonVisibleProperty,
         new Binding(nameof(BaseViewModel.IsBackButtonVisible), 
              mode: BindingMode.OneWayToSource));
}

还建议为 ForceNoBackButton 使用属性更改的处理程序-这样您就可以处理对其值的更改(如果更改是在页面加载后发生的).

Would also recommend to have a property-changed handler for ForceNoBackButton - so you can handle changes to it's value (if they happen after the page has already loaded).

这篇关于如何在Xamarin表单中使用ControlTemplate进行替代绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆