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”
+0

结合还不能正常工作。它只有在我将其设置为true/false时才有效,但似乎我无法将其绑定到视图模型属性 – Marco24690

+0

上面的代码确实对我有用。诀窍是从可绑定对象设置OnAttachedTo(BindableObject)上的绑定上下文。这对我来说似乎是一种破绽,但我怀疑行为不是被设计成可绑定的,或者是XF代码中存在一个错误。您可能想在Bugzilla中创建一个错误报告。 – SKall

+0

我没有添加OnAttachedTo方法。现在它也适用于Button。谢谢 – Marco24690