我有以下风格
<Style x:Key="GreenButtonStyle" BasedOn="{StaticResource MyButtonBaseStyle}" TargetType="Button">
<Style.Triggers>
<Trigger TargetType="Button" Property="IsEnabled" Value="False">
<Setter Property="BackgroundColor" Value="Silver" />
<Setter Property="TextColor" Value="Black" />
</Trigger>
<Trigger TargetType="Button" Property="IsEnabled" Value="True">
<Setter Property="BackgroundColor" Value="Green" />
<Setter Property="TextColor" Value="Orange" />
</Trigger>
</Style.Triggers>
</Style>
我在以下视图中使用。
<Button x:Name="ConfirmButton"
Text="Confirm"
Style="{StaticResource GreenButtonStyle}"
IsEnabled="{Binding Source={x:Reference Some}, Path=ConfirmEnabled}"
/>
<Button x:Name="ToggleButton"
Text="Toggle"
Clicked="Toggle_Clicked"
/>
后面的代码(只是片段)
public partial class SomeView : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _confirmEnabled = false;
public bool ConfirmEnabled
{
get { return _confirmEnabled; }
}
private void Toggle_Clicked(object sender, EventArgs e)
{
_confirmEnabled = !_confirmEnabled;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ConfirmEnabled)));
}
}
当View进入游戏状态时,按钮处于非活动状态时一切正常。当我单击切换按钮时,字体会根据需要将颜色更改为橙色,但背景不会将颜色更改为绿色。
如果我单击两次切换(禁用然后启用),则字体为橙色,背景最终为绿色。
任何人都知道为什么在第一次将ConfirmEnabled更改为true时背景颜色没有改变?
答案 0 :(得分:0)
我建议您使用MVVM方法进行应用设计。创建一个名为BaseViewModel.cs
的类和另一个名为SomeViewModel.cs
的类,并按如下方式编写它们:
BaseViewModel.cs,每个视图模型都应该继承。它允许您使用PropertyChanged
个事件:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
SomeViewModel.cs。现在每次更改ConfirmEnabled
的值时,一旦设置了绑定,视图就会自动检测到更改:
public class SomeViewModel : BaseViewModel
{
private bool _confirmEnabled = false;
public bool ConfirmEnabled
{
get { return _confirmEnabled; }
set
{
_confirmEnabled = value;
OnPropertyChanged(nameof(ConfirmEnabled));
}
}
}
现在,对于你的页面SomeView.cs:
public partial class SomeView : ContentPage, INotifyPropertyChanged
{
SomeViewModel _viewModel;
public SomeView()
{
InitializeComponent();
_viewModel = new SomeViewModel();
BindingContext = _viewModel;
}
private void Toggle_Clicked(object sender, EventArgs e)
{
_viewModel.ConfirmEnabled = !_viewModel.ConfirmEnabled;
}
}
你的按钮代码:
<Button x:Name="ConfirmButton"
Text="Confirm"
Style="{StaticResource GreenButtonStyle}"
IsEnabled="{Binding ConfirmEnabled}"
/>
<Button x:Name="ToggleButton"
Text="Toggle"
Clicked="Toggle_Clicked"
/>
答案 1 :(得分:0)
结束实现我自己的按钮控制,它基本上是两个按钮,然后根据它是启用还是禁用我隐藏或显示另一个。
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyProject.Views._Controls.MyButton">
<Grid>
<Button x:Name="WhenEnabledButton"
Clicked="WhenEnabledButton_Clicked"
Text="WhenEnabled"></Button>
<Button x:Name="WhenDisabledButton"
Text="WhenDisabled"></Button>
<Label x:Name="DisabledButtonCoveringLabel" BackgroundColor="Transparent"></Label>
</Grid>
</ContentView>
背后的代码
namespace MyProject.Views._Controls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyButton : ContentView
{
#region Property Bindings
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(MyButton),
null, propertyChanged: (bo, o, n) => ((MyButton)bo).OnCommandChanged());
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object),
typeof(MyButton), null,
propertyChanged: (bindable, oldvalue, newvalue) => ((MyButton)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
public static readonly new BindableProperty IsEnabledProperty =
BindableProperty.Create(
propertyName: "IsEnabled",
returnType: typeof(Boolean),
declaringType: typeof(MyButton),
defaultValue: false,
defaultBindingMode: BindingMode.OneWay,
propertyChanged: IsEnabledChanged);
private static void IsEnabledChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (MyButton)bindable;
bool enabled = (bool)newValue;
control.WhenEnabledButton.IsVisible = enabled;
control.WhenDisabledButton.IsVisible = !enabled;
if (Device.RuntimePlatform == Device.WinPhone || Device.RuntimePlatform == Device.WinRT)
{
control.DisabledButtonCoveringLabel.IsVisible = !enabled;
}
}
public static readonly BindableProperty TextProperty =
BindableProperty.Create(
propertyName: "Text",
returnType: typeof(string),
declaringType: typeof(MyButton),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.OneWay,
propertyChanged: TextChanged);
private static void TextChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (MyButton)bindable;
control.WhenEnabledButton.Text = (string)newValue;
control.WhenDisabledButton.Text = (string)newValue;
}
public static readonly BindableProperty EnabledStyleProperty =
BindableProperty.Create(
propertyName: "EnabledStyle",
returnType: typeof(Style),
declaringType: typeof(MyButton),
defaultBindingMode: BindingMode.OneWay,
propertyChanged: EnabledStyleChanged);
private static void EnabledStyleChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (MyButton)bindable;
control.WhenEnabledButton.Style = (Style)newValue;
}
public static readonly BindableProperty DisabledStyleProperty =
BindableProperty.Create(
propertyName: "DisabledStyle",
returnType: typeof(Style),
declaringType: typeof(MyButton),
defaultBindingMode: BindingMode.OneWay,
propertyChanged: DisabledStyleChanged);
private static void DisabledStyleChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (MyButton)bindable;
control.WhenDisabledButton.Style = (Style)newValue;
}
#endregion
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public string Text
{
get
{
return this.GetValue<string>(TextProperty);
}
set
{
this.SetValue(TextProperty, value);
}
}
public new bool IsEnabled
{
get
{
return this.GetValue<bool>(IsEnabledProperty);
}
set
{
this.SetValue(IsEnabledProperty, value);
}
}
#region Click event
public delegate void ClickedHandler(object sender, EventArgs e);
public event ClickedHandler Clicked;
private void WhenEnabledButton_Clicked(object sender, EventArgs e)
{
if (Clicked != null)
this.Clicked.Invoke(sender, e);
else
this.Command.Execute(this.CommandParameter);
}
void CommandCanExecuteChanged(object sender, EventArgs eventArgs)
{
ICommand cmd = Command;
if (cmd != null)
IsEnabled = cmd.CanExecute(CommandParameter);
}
void OnCommandChanged()
{
if (Command != null)
{
Command.CanExecuteChanged += CommandCanExecuteChanged;
CommandCanExecuteChanged(this, EventArgs.Empty);
}
else
IsEnabled = true;
}
#endregion
public MyButton()
{
InitializeComponent();
if (Device.RuntimePlatform == Device.Android)
{
DisabledButtonCoveringLabel.IsVisible = false;
WhenDisabledButton.IsEnabled = false;
}
else if (Device.RuntimePlatform == Device.WinPhone || Device.RuntimePlatform == Device.WinRT)
{
DisabledButtonCoveringLabel.IsVisible = true;
WhenDisabledButton.IsEnabled = true;
}
this.SetValue(EnabledStyleProperty, Application.Current.Resources["GreenEnabledButtonStyle"]);
this.SetValue(DisabledStyleProperty, Application.Current.Resources["GreenDisabledButtonStyle"]);
}
}
}