如何在Xamarin表单中使用ControlTemplate进行替代绑定 [英] How to do alternative binding with ControlTemplate in Xamarin Forms
问题描述
我正在使用 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="<"
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..
-
如果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屋!