Ever wanted to change the way the Xamarin.Forms disabled button looks? For example, changing the background color and text color, or the shape?
Here’s a quick tip with no custom renderers to build a Xamarin.Forms Button
that can have its style updated when the IsEnabled
is set to false. The concept is basically to create a class that inherits from Button
, and keep track of the original Style
property, then add a BindableProperty
for the style to apply when disabled, and flip between the two when IsEnabled
changes.
Here is what that class looks like:
DisablingButton.cs
/// <summary> /// Xamarin.Forms Button that allows for applying a different style when enabled. /// </summary> public class DisablingButton : Button { private Style _normalStyle; public static readonly BindableProperty DisabledStyleProperty = BindableProperty.Create(nameof(DisabledStyle), typeof(Style), typeof(DisablingButton), null, BindingMode.TwoWay, null, (obj, oldValue, newValue) => { }); public Style DisabledStyle { get { return (Style)GetValue(DisabledStyleProperty); } set { SetValue(DisabledStyleProperty, value); } } public DisablingButton() { _normalStyle = Style; PropertyChanged += ExtendedButton_PropertyChanged; } private void ExtendedButton_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(IsEnabled) && DisabledStyle != null) { if (IsEnabled) Style = _normalStyle; else Style = DisabledStyle; } } }
So now we can use this with two different styles, and bind it all in our XAML. For example –
Styles.xaml
... <Style x:Key="StickyBlueButton" TargetType="Button"> <Setter Property="HeightRequest" Value="50"/> <Setter Property="BackgroundColor" Value="{DynamicResource BlueAccentColor}"/> <Setter Property="TextColor" Value="White"/> <Setter Property="BorderRadius" Value="0"/> <Setter Property="FontSize" Value="16"/> <Setter Property="FontAttributes" Value="Bold"/> <Setter Property="Margin" Value="0"/> <Setter Property="HorizontalOptions" Value="FillAndExpand"/> <Setter Property="FontFamily" Value="{StaticResource ProximaNovaBold}"/> <Setter Property="VerticalOptions" Value="End"/> </Style> <Style x:Key="StickyBlueButtonDisabled" TargetType="Button"> <Setter Property="HeightRequest" Value="50"/> <Setter Property="BackgroundColor" Value="{DynamicResource LightGray}"/> <Setter Property="TextColor" Value="White"/> <Setter Property="BorderRadius" Value="0"/> <Setter Property="FontSize" Value="16"/> <Setter Property="FontAttributes" Value="Bold"/> <Setter Property="Margin" Value="0"/> <Setter Property="HorizontalOptions" Value="FillAndExpand"/> <Setter Property="FontFamily" Value="{StaticResource ProximaNovaBold}"/> <Setter Property="VerticalOptions" Value="End"/> </Style> ...
and then use them in the page…
MainPage.xaml
... <components:DisablingButton IsEnabled="{Binding IsEnabled}" Command="{Binding CreateNewItemCommand}" Style="{DynamicResource StickyBlueButton}" DisabledStyle="{DynamicResource StickyBlueButtonDisabled}" Text="Add item" /> ...
And here’s what it looks like!
IsEnabled = true
IsEnabled = false
If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!
Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.
Why is Style null in the constructor ?
_normalStyle = Style;
I am getting null and _normalStyle is not being set
LikeLike
Do you not have a Style value set in your XAML or in default ctor?
LikeLike
I’m having the same problem like Bilimoria. Style is null in the constructor. Can you please elaborate how to solve this? Thank you very much!
LikeLike
Did you see my reply to them? Do you have a style set in the XAML?
LikeLike
In the MainPage.xaml example you show that the style property ist set to a dynamic resource (Style=”{DynamicResource StickyBlueButton}”). How can I assign another style in XAML at the same time?
LikeLike
Executing the set in code will override the XAML set
LikeLike
Like it! Well done!
LikeLike