Xamarin形式ToggleButton
问题描述:
我有一个PCL,我正在使用MVVM模式。 我正在构建一个togglebutton,它在viewmodel中的相关属性被激活时触发,具有行为和触发器。 这是我的行为Xamarin形式ToggleButton
public class ToggleBehavior : Behavior<View>
{
TapGestureRecognizer tapRecognizer;
public static readonly BindableProperty IsToggledProperty = BindableProperty.Create<ToggleBehavior, bool>(tb => tb.IsToggled, false);
public bool IsToggled
{
set { SetValue(IsToggledProperty, value); }
get { return (bool)GetValue(IsToggledProperty); }
}
}
这是我如何消费自己的行为
<Button Text="AUTO" Style="{StaticResource SmallEllipseButton}" BackgroundColor="{StaticResource BackgroundColor}" cm:Message.Attach="Automatic($dataContext)">
<Button.Behaviors>
<local:ToggleBehavior x:Name="autoToggleBehavior" IsToggled="{Binding CurrentMode,Converter={StaticResource modeToBooleanConverter}, ConverterParameter=AUTO}"/>
</Button.Behaviors>
<Button.Triggers>
<DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference autoToggleBehavior},Path=IsToggled}" Value="False" >
<Setter Property="BackgroundColor" Value="White"/>
<Setter Property="BorderColor" Value="White"/>
<Setter Property="TextColor" Value="Gray"/>
</DataTrigger>
<DataTrigger TargetType="Button" Binding="{Binding Source={x:Reference autoToggleBehavior},Path=IsToggled}" Value="True" >
<Setter Property="BackgroundColor" Value="{StaticResource BackgroundColor}"/>
<Setter Property="TextColor" Value="White"/>
</DataTrigger>
</Button.Triggers>
</Button>
的问题是,物业IsToggled未正确在此IsToggled="{Binding CurrentMode,Converter={StaticResource modeToBooleanConverter}, ConverterParameter=AUTO}"/>
如果我将它设置静态为true或false绑定有用。 我认为的问题是,我无法将这个属性用dinamically绑定。 我在同一页面使用与同一个转换器的IsVisible属性相同的绑定,并且它可以工作。 如果我在转换器中放置一个断点,应用程序不会中断它,但IsVisible属性会中断。
答
使用按钮可能不是最好的选择,因为它已经有一个水龙头处理程序,并将其分配给它仍然不会触发事件。我不知道这是否有帮助,但我将控件更改为标签以使下面的工作。当然,如果Button绑定到修改视图模型的命令,那么您根本不需要tap控制器。
XAML:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:BehTest" x:Class="BehTest.BehTestPage">
<Label Text="AUTO" HorizontalOptions="Center" VerticalOptions="Center">
<Label.Behaviors>
<local:ToggleBehavior x:Name="autoToggleBehavior" IsToggled="{Binding Toggled, Mode=TwoWay}"/>
</Label.Behaviors>
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference autoToggleBehavior},Path=IsToggled}" Value="False" >
<Setter Property="BackgroundColor" Value="White"/>
<Setter Property="TextColor" Value="Gray"/>
</DataTrigger>
<DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference autoToggleBehavior},Path=IsToggled}" Value="True" >
<Setter Property="BackgroundColor" Value="Blue"/>
<Setter Property="TextColor" Value="White"/>
</DataTrigger>
</Label.Triggers>
</Label>
</ContentPage>
行为:
public class ToggleBehavior : Behavior<View>
{
readonly TapGestureRecognizer tapRecognizer;
public ToggleBehavior()
{
tapRecognizer = new TapGestureRecognizer
{
Command = new Command(() => this.IsToggled = !this.IsToggled)
};
}
public static readonly BindableProperty IsToggledProperty = BindableProperty.Create<ToggleBehavior, bool>(tb => tb.IsToggled, false);
public bool IsToggled
{
set { SetValue(IsToggledProperty, value); }
get { return (bool)GetValue(IsToggledProperty); }
}
protected override void OnAttachedTo(View bindable)
{
base.OnAttachedTo(bindable);
bindable.GestureRecognizers.Add(this.tapRecognizer);
}
protected override void OnDetachingFrom(View bindable)
{
base.OnDetachingFrom(bindable);
bindable.GestureRecognizers.Remove(this.tapRecognizer);
}
protected override void OnAttachedTo(BindableObject bindable)
{
base.OnAttachedTo(bindable);
this.BindingContext = bindable.BindingContext;
bindable.BindingContextChanged += Bindable_BindingContextChanged;
}
protected override void OnDetachingFrom(BindableObject bindable)
{
base.OnDetachingFrom(bindable);
this.BindingContext = null;
bindable.BindingContextChanged -= Bindable_BindingContextChanged;
}
void Bindable_BindingContextChanged(object sender, EventArgs e)
{
var bobject = sender as BindableObject;
this.BindingContext = bobject?.BindingContext;
}
}
标签为 “IsToggled”
结合还不能正常工作。它只有在我将其设置为true/false时才有效,但似乎我无法将其绑定到视图模型属性 – Marco24690
上面的代码确实对我有用。诀窍是从可绑定对象设置OnAttachedTo(BindableObject)上的绑定上下文。这对我来说似乎是一种破绽,但我怀疑行为不是被设计成可绑定的,或者是XF代码中存在一个错误。您可能想在Bugzilla中创建一个错误报告。 – SKall
我没有添加OnAttachedTo方法。现在它也适用于Button。谢谢 – Marco24690