ImageButtonというカスタムコントロールを作成しました。これにより、Up、Down、およびInactiveステートの異なるイメージを設定できます。 「通常」モードまたは「ラッチ」モードでも動作できます。XamarinフォームカスタムコントロールとBindableプロパティが期待どおりに動作しない
小さな小片以外は正常に動作します.XAMLで設定した値はすぐに適用されません。デフォルト値のみを使用します。
<custom:ImageButton
Source="i_left.png"
SourceUp="i_left.png"
SourceDown="i_right.png"
SourceInactive="i_close.png"
Toggle="True"
ToggleState="Up"
WidthRequest="{StaticResource IconMedium}"
HeightRequest="{StaticResource IconMedium}"
Command="{Binding ImageButton1Command}"/>
私は「ソース」を指定する必要はありません。ここで
ボタンは、私はそうのような「ソース」でそれを設定した場合に動作ImageButton.cs
public class ImageButton : Image
{
public enum State
{
Inactive,
Up,
Down
};
public static readonly BindableProperty CommandProperty =
BindableProperty.Create("Command", typeof(ICommand), typeof(ImageButton), null);
public static readonly BindableProperty SourceUpProperty =
BindableProperty.Create("SourceUp", typeof(string), typeof(ImageButton), null);
public static readonly BindableProperty SourceDownProperty =
BindableProperty.Create("SourceDown", typeof(string), typeof(ImageButton), null);
public static readonly BindableProperty SourceInactiveProperty =
BindableProperty.Create("SourceInactive", typeof(string), typeof(ImageButton), null);
public static readonly BindableProperty ToggleProperty =
BindableProperty.Create("Toggle", typeof(bool), typeof(ImageButton), false);
public static readonly BindableProperty ToggleStateProperty =
BindableProperty.Create("ToggleState", typeof(State), typeof(ImageButton), State.Up, BindingMode.TwoWay);
public ImageButton()
{
Initialize();
}
public void Initialize()
{
switch (ToggleState) // <- this is returning "State.Up" (the default) no matter what is set in the xaml.
{
case State.Up:
Source = SourceUp;
break;
case State.Down:
Source = SourceDown;
break;
case State.Inactive:
Source = SourceInactive;
break;
default:
Source = SourceUp;
break;
}
GestureRecognizers.Add(new TapGestureRecognizer
{
Command = TransitionCommand
});
}
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
private ICommand TransitionCommand
{
get
{
return new Command(async() =>
{
if (ToggleState != State.Inactive)
{
AnchorX = 0.48;
AnchorY = 0.48;
await this.ScaleTo(0.8, 50, Easing.Linear);
if (Toggle)
{
if (ToggleState == State.Down)
ToggleState = State.Up;
else
ToggleState = State.Down;
}
await this.ScaleTo(1, 50, Easing.Linear);
if (Command != null)
{
Command.Execute(null);
}
}
});
}
}
public string SourceUp
{
get { return (string)GetValue(SourceUpProperty); }
set { SetValue(SourceUpProperty, value); }
}
public string SourceDown
{
get { return (string)GetValue(SourceDownProperty); }
set { SetValue(SourceDownProperty, value); }
}
public string SourceInactive
{
get { return (string)GetValue(SourceInactiveProperty); }
set { SetValue(SourceInactiveProperty, value); }
}
public bool Toggle
{
get { return (bool)GetValue(ToggleProperty); }
set { SetValue(ToggleProperty, value); }
}
public State ToggleState
{
get { return (State)GetValue(ToggleStateProperty); }
set
{
SetValue(ToggleStateProperty, value);
switch (value)
{
case State.Up:
Source = SourceUp;
break;
case State.Down:
Source = SourceDown;
break;
case State.Inactive:
Source = SourceInactive;
break;
default:
Source = SourceUp;
break;
}
}
}
}
ですなぜならコンストラクタでは私は初期状態に合わせて設定しているからです。
しかし、 "ToggleState"はまだ私のxaml値に設定されていないようです。
私はこの
<custom:ImageButton
SourceUp="i_left.png"
SourceDown="i_right.png"
SourceInactive="i_close.png"
Toggle="True"
ToggleState="Down"
WidthRequest="{StaticResource IconMedium}"
HeightRequest="{StaticResource IconMedium}"
Command="{Binding ImageButton1Command}"/>
好きで、それが「i_right.png」の画像の上にあるべき負荷時にそれを設定しようとしていますが、そうではありません。
回答を編集:次のクラスは期待どおり動作します!
public class ImageButton : Image
{
public enum State
{
Inactive,
Up,
Down
};
public static readonly BindableProperty CommandProperty =
BindableProperty.Create("Command", typeof(ICommand), typeof(ImageButton), null, propertyChanged: OnStateChanged);
public static readonly BindableProperty SourceUpProperty =
BindableProperty.Create("SourceUp", typeof(ImageSource), typeof(ImageButton), null, propertyChanged: OnStateChanged);
public static readonly BindableProperty SourceDownProperty =
BindableProperty.Create("SourceDown", typeof(ImageSource), typeof(ImageButton), null, propertyChanged: OnStateChanged);
public static readonly BindableProperty SourceInactiveProperty =
BindableProperty.Create("SourceInactive", typeof(ImageSource), typeof(ImageButton), null, propertyChanged: OnStateChanged);
public static readonly BindableProperty ToggleProperty =
BindableProperty.Create("Toggle", typeof(bool), typeof(ImageButton), false);
public static readonly BindableProperty ToggleStateProperty =
BindableProperty.Create("ToggleState", typeof(State), typeof(ImageButton), State.Up, BindingMode.TwoWay, propertyChanged: OnStateChanged);
public ImageButton()
{
Initialize();
}
public void Initialize()
{
GestureRecognizers.Add(new TapGestureRecognizer
{
Command = TransitionCommand
});
}
static void OnStateChanged(BindableObject bindable, object oldValue, object newValue)
{
var imageButton = bindable as ImageButton;
imageButton.SetState();
}
public void SetState()
{
switch (ToggleState)
{
case State.Up:
Source = SourceUp;
break;
case State.Down:
Source = SourceDown;
break;
case State.Inactive:
Source = SourceInactive;
break;
default:
Source = SourceUp;
break;
}
}
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
private ICommand TransitionCommand
{
get
{
return new Command(async() =>
{
if (ToggleState != State.Inactive)
{
AnchorX = 0.48;
AnchorY = 0.48;
await this.ScaleTo(0.8, 50, Easing.Linear);
if (Toggle)
{
if (ToggleState == State.Down)
ToggleState = State.Up;
else
ToggleState = State.Down;
}
await this.ScaleTo(1, 50, Easing.Linear);
if (Command != null)
{
Command.Execute(null);
}
}
});
}
}
public ImageSource SourceUp
{
get { return (ImageSource)GetValue(SourceUpProperty); }
set { SetValue(SourceUpProperty, value); }
}
public ImageSource SourceDown
{
get { return (ImageSource)GetValue(SourceDownProperty); }
set { SetValue(SourceDownProperty, value); }
}
public ImageSource SourceInactive
{
get { return (ImageSource)GetValue(SourceInactiveProperty); }
set { SetValue(SourceInactiveProperty, value); }
}
public bool Toggle
{
get { return (bool)GetValue(ToggleProperty); }
set { SetValue(ToggleProperty, value); }
}
public State ToggleState
{
get { return (State)GetValue(ToggleStateProperty); }
set { SetValue(ToggleStateProperty, value); }
}
}
ありがとうございました。私は簡単にそれを試み、あなたが言ったように、XAMLによって設定されるプロパティ値の順序/順序が問題であることに気づいた。私は論理を再考し、私がそれを並べ替えることができるかどうかを見ます。 –
すごくうまくいった!ありがとうございました。私は今もまた修正する別のコントロールを持っています..もう一度ありがとう! –