【发布时间】:2017-10-05 21:46:38
【问题描述】:
我制作了一个名为 ImageButton 的自定义控件,它允许我为 Up、Down 和 Inactive 状态设置不同的图像。 它还可以在“正常”模式或“锁定”模式下运行。
除了一小块外它工作正常……我在 XAML 中设置的值不会立即应用。它只使用默认值。
这是 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;
}
}
}
}
如果我用这样的“源”设置按钮,则该按钮可以工作:
<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}"/>
我不需要指定“Source”,因为在构造函数中我根据初始状态设置它。
但似乎“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); }
}
}
【问题讨论】:
标签: xamarin.forms custom-controls