2016-07-13 11 views
3

私はPCLを持っており、MVVMパターンを使用しています。 ビヘイビアとトリガを使用して、ビューモデルの関連プロパティがアクティブになったときに切り替えるトグルボタンを作成しています。 これはこれは私が私の行動を消費する方法である私の行動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> 

問題は、私がtrueまたはfalseに静的に設定した場合IsToggledこのIsToggled="{Binding CurrentMode,Converter={StaticResource modeToBooleanConverter}, ConverterParameter=AUTO}"/> に正しくバインドされていないプロパティできます。 私はこのプロパティをdinamicallyバインドすることはできないと思う問題です。 IsVisibleプロパティで同じページ内の同じコンバータで同じバインディングを使用すると、それは機能します。 コンバータにブレークポイントを置くと、アプリケーションは中断されませんが、IsVisibleプロパティはブレークします。

答えて

1

ボタンを使用することは、すでにタップハンドラを持っており、それに割り当ててもイベントをトリガしないため、最良のオプションではない可能性があります。これが役立つかどうかは分かりませんが、コントロールをラベルに変更して、下のコードを動作させるようにしました。もちろん、ボタンがビューモデルを変更するコマンドにバインドされている場合、ビヘイビアにタップハンドラはまったく必要ありません。

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> 

行動:

ラベル "IsToggled" とも
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

動作しませんバインディング。 true/falseに設定した場合にのみ機能しますが、viewmodelプロパティにバインドできないようです。 – Marco24690

+0

上記のコードは私のバインディングで機能しました。そのトリックは、バインド可能なオブジェクトからOnAttachedTo(BindableObject)のバインディングコンテキストを設定することでした。これは私にとってはハックのようですが、Behaviorがバインド可能でないか、XFコードにバグがあると思われます。 Bugzillaでバグレポートを作成したいかもしれません。 – SKall

+0

OnAttachedToメソッドを追加しませんでした。今それはボタンでも動作します。ありがとう – Marco24690