I am working on a Xamarin.Forms UWP application and I wanted to change my button's background colour when pressed. I have been searching the web and the most straightforward way I could find is this:
private void Button_OnClicked(object s, EventArgs e)
{
var b = (Button) s;
var originalColour = b.BackgroundColor;
b.BackgroundColor = Color.DarkOrange;
Device.StartTimer(TimeSpan.FromSeconds(0.25), () =>
{
b.BackgroundColor = originalColour;
return false;
});
}
However, personally, I am not liking this approach very much. How can this be done better?
An EventTrigger solution in XAML:
Implement the following in MyAssembly
, e.g. the portable assembly containing App.xaml:
using Xamarin.Forms;
namespace MyNamespace
{
public class ButtonTriggerAction : TriggerAction<VisualElement>
{
public Color BackgroundColor { get; set; }
protected override void Invoke(VisualElement visual)
{
var button = visual as Button;
if (button == null) return;
if (BackgroundColor != null) button.BackgroundColor = BackgroundColor;
}
}
}
XAML:
xmlns:local="clr-namespace:MyNamespace;assembly=MyAssembly"
...
<Button Text="EventTrigger">
<Button.Triggers>
<EventTrigger Event="Pressed">
<local:ButtonTriggerAction BackgroundColor="Red" />
</EventTrigger>
<EventTrigger Event="Released">
<local:ButtonTriggerAction BackgroundColor="Default" />
</EventTrigger>
</Button.Triggers>
</Button>
a more natural and cleaner way to do it would be using VisualStateManager
<Button Text="Click Me!">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
you can read more about in here.
This is the simplest solution but of course not very clean.
THe problem here is that each platform implements the "pressed" state differently and Xamarin.Forms doesn't have any built-in way how to handle this.
In case of UWP, you have two options. First, you can create a new default button style that will be used throughout your app. You can find the default style here, and just copy it, modify the Pressed
VisualState
and add is as a default resource:
<Style TargetType="Button">
<!-- ... your style -->
</Style>
However, if the pressed button color should be applied only in some places, you should rather create a new view that derives from button and uses a custom renderer on UWP that applies a custom style in the OnElementChanged
event handler:
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (this.Element != null)
{
this.Control.Style = ( Style )Application.Current.Resources["CustomButtonStyle"];
}
}
Other platforms will have similar solutions as well, but you will definitely have to implement them in such platform-specific way, probably using the custom renderers.
For more information on custom renderers see the documentation. You may also find some inspiration in Xamarin.Forms Labs repository.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With