2016-07-13 34 views
3

Ich habe eine PCL und ich verwende MVVM Muster. Ich baue ein togglebutton, das schaltet, wenn die zugehörige Eigenschaft im Viewmodel aktiviert ist, mit Verhalten und Triggern. Das ist mein VerhaltenXamarin Forms 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); } 
    } 
} 

Dies ist, wie ich mein Verhalten verbrauchen

       <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> 

Das Problem ist, dass die Eigenschaft isToggled nicht korrekt in diesem IsToggled="{Binding CurrentMode,Converter={StaticResource modeToBooleanConverter}, ConverterParameter=AUTO}"/> binded ist, wenn ich es statisch wahr oder falsch gesetzt Es klappt. Das Problem, das ich denke, ist, dass ich diese Eigenschaft nicht dynamisch binden kann. Ich benutze die gleiche Bindung mit dem gleichen Konverter auf der gleichen Seite für eine IsVisible-Eigenschaft und es funktioniert. Wenn ich einen Haltepunkt in den Konverter setzen, bricht die Anwendung nicht in es, aber für die IsVisible-Eigenschaft bricht.

Antwort

1

Die Verwendung einer Schaltfläche ist möglicherweise nicht die beste Option, da sie bereits über einen Tipp-Handler verfügt und das Zuweisen eines Ereignisses das Ereignis immer noch nicht auslösen würde. Ich weiß nicht, ob das hilft, aber ich habe das Steuerelement in ein Label geändert, damit das unten stehende funktioniert. Wenn die Schaltfläche an einen Befehl gebunden ist, der das Ansichtsmodell ändert, brauchen Sie den Tipp-Handler natürlich überhaupt nicht.

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> 

Verhalten:

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; 
    } 
} 
+0

auch mit dem Label "isToggled" Bindung funktioniert nicht. Es funktioniert nur, wenn ich es auf wahr/falsch setze, aber es scheint, dass ich es nicht an eine Viewmodel-Eigenschaft binden kann – Marco24690

+0

Der obige Code hat für Bindungen für mich funktioniert. Der Trick bestand darin, den Bindungskontext für das OnAttachedTo (BindableObject) vom bindbaren Objekt festzulegen. Das scheint mir ein Hack zu sein, aber ich vermute, dass entweder das Verhalten nicht bindbar ist oder ein Fehler im XF-Code vorliegt. Vielleicht möchten Sie in Bugzilla einen Fehlerbericht erstellen. – SKall

+0

Ich habe die OnAttachedTo-Methode nicht hinzugefügt. Jetzt klappt es, auch mit Button. Vielen Dank – Marco24690