我有一个PCL,我正在使用MVVM模式.
我正在构建一个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 =“{Binding CurrentMode,Converter = {StaticResource modeToBooleanConverter},ConverterParameter = AUTO}”/>中,属性IsToggled没有正确绑定.
如果我将其静态设置为true或false,则可以正常工作.
我认为的问题是我无法将这个属性与dinamically绑定.
我在同一页面中对同一个转换器使用相同的绑定作为IsVisible属性,它可以工作.
如果我在转换器中放置一个断点,应用程序不会中断它,但是对于IsVisible属性会中断.
最佳答案 使用Button可能不是最好的选择,因为它已经有一个tap处理程序,并且为它分配一个仍然不会触发事件.我不知道这是否有帮助,但我将控件更改为Label以使下面的工作正常.当然,如果将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;
}
}