Xamarin Forms 切换按钮

4

我有一个PCL并且正在使用MVVM模式。 我正在构建一个ToggleButton,当ViewModel中相关属性被激活时,使用Behaviors和Triggers来切换。 这是我的Behavior:

 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,则可以工作。 问题我认为是我无法动态绑定此属性。 我在同一页中使用相同的绑定和相同的转换器来处理IsVisible属性,它可以正常工作。 如果我在转换器中设置断点,则应用程序不会在其中中断,但对于IsVisible属性则会中断。
2个回答

2

使用按钮可能不是最佳选择,因为它已经有一个点击处理程序,并将其分配给它仍然无法触发事件。我不知道这是否有帮助,但我更改了控件以使标签下面的内容正常工作。当然,如果按钮绑定到修改视图模型的命令,则根本不需要在行为中使用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)设置绑定上下文。这看起来像是一个hack,但我怀疑Behavior可能并不是设计为可绑定的,或者XF代码中存在错误。您可能希望在Bugzilla中创建一个错误报告。 - SKall
我没有添加OnAttachedTo方法。现在它可以正常工作,包括按钮。谢谢。 - Marco24690
你们能帮我吗?@Marco24690 上面的代码对我有效,但我是在listview中使用它,我想要一个单独的绑定。例如,如果我在一行上有2个标签,如果我单击其中一个,则两个标签的切换属性都会触发,我只想让这些控件单独工作。 - Ronak Shethia
@RonakShethia 看起来你应该创建两个 ToggleBehavior 对象。一个用于每个标签。 - SKall

-1
我们在NuGet!中添加了一个ToggleButton。 它是免费使用的。
xmlns:aw="clr-namespace:AscendantWare.Xamarin.Essentials.Controls"

<aw:AWToggleButton TextColor="White" ToggleBackgroundColor="DarkGoldenrod" Margin="0" VerticalOptions="FillAndExpand" HorizontalOptions="Fill" CornerRadius="15" IsToggled="{Binding IsNoteEnabled, Mode=TwoWay}" Command="{Binding MyCommand}"/>

更多信息请参阅我们的在线文档这里!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接