I've found an issue where triggers on a button style are not re-evaluating when a value changes if the button is in a listview and an item is deleted from the listview.
This occurs on Android only.
Here's a cut down sample of my style:
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="#F2F2F2" /><!-- gray -->
<Setter Property="Text" Value="A" />
<Style.Triggers>
<Trigger Property="controls:ButtonExtensions.IsPrimary" Value="True" TargetType="Button">
<Setter Property="BackgroundColor" Value="#FAC54A" /> <!-- orange -->
<Setter Property="Text" Value="B" />
</Trigger>
</Style.Triggers>
</Style>
- These buttons are in ViewCell's within a ListView.
- The ListView is bound to an ObservableCollection
- The collection contains 2 models, the first item has "IsPrimary=false" and the second item has "IsPrimary=true"
- Delete the first item from the collection
Expected result:
The list contains one item. The button has "Text=A" and a color of orange.
Actual result
The list contains one item. The button has "Text=A" but the color is gray.
You can see that the trigger is firing, because the text is updated. But the background is not updated.
I've got a workaround by copying the existing ButtonRenderer and changing the following line of code in the OnElementPropertyChanged method of the Android renderer:
before:
if (this.drawableEnabled && (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName || e.PropertyName == Button.BorderColorProperty.PropertyName || e.PropertyName == Button.BorderRadiusProperty.PropertyName || e.PropertyName == Button.BorderWidthProperty.PropertyName)) {
this.backgroundDrawable.Reset ();
base.Control.Invalidate ();
}
after:
if (this.drawableEnabled && (e.PropertyName == "Renderer" || e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName || e.PropertyName == Button.BorderColorProperty.PropertyName || e.PropertyName == Button.BorderRadiusProperty.PropertyName || e.PropertyName == Button.BorderWidthProperty.PropertyName)) {
this.backgroundDrawable.Reset ();
base.Control.Invalidate ();
}
So when the button is redrawn after ListView item is deleted, this causes the background drawable resource to be recalculated... Don't know if this is a "proper" fix or just a hack, but it's the only way I could get it to work...