Search code examples
xamarin.formscustom-rendererxaml-binding

Custom Render not being used on Bindable property update


Please consider the following issue.

In my Xamarin.Forms app I have a custom render for UWP that allows for a button to have two lines, and be centralised.

The buttons in questions are items in a Listview that are bound to objects. When they are initially generated, they display correctly with both lines of text in the center of the button, however if I update the text, it updates, but seems to bypass the custom renders "be in the center" code.

Please see the below code snippets and images to explain the situation further.

Custom Render

[assembly: ExportRenderer(typeof(TwoLinedButton), typeof(TwoLinedButtonUWP))]
namespace aphiresawesomeproject.UWP
{
    public class TwoLinedButtonUWP : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (Control != null && e.NewElement.Text != null)
            {
                var textBlock = new Windows.UI.Xaml.Controls.TextBlock
                {
                    Text = e.NewElement.Text,
                    TextAlignment = Windows.UI.Xaml.TextAlignment.Center,
                    TextWrapping = TextWrapping.WrapWholeWords
                };
                Control.Content = textBlock;
            }
        }
    }
}

XAML

<ListView x:Name="AphiresListView" CachingStrategy="RecycleElement" ItemsSource="{Binding ListViewItems}" Margin="0,20,0,0" RowHeight="130" SeparatorVisibility="None" VerticalOptions="FillAndExpand" Grid.Column="1" Grid.Row ="3" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <local:TwoLinedButton Command="{Binding ClickedCommand}" Margin="5,10,5,10" HorizontalOptions ="FillAndExpand" BackgroundColor="{Binding color_hex}" Grid.Column="1" TextColor="{StaticResource LightTextColor}" FontSize="Medium" Text="{Binding problem_title}"></local:TwoLinedButton>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Update in Viewmodel

foreach (AphiresObject ViewItem in ListViewItems)
{
    ViewItem.problem_title = ViewItem.problem_title.Replace("Line 2", "Updated Line 2");
}

Before

enter image description here

After

enter image description here


Solution

  • I think all you need to do is override OnElementPropertyChanged in your renderer and set the textBlock properties again when your text property changes.

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
    
        if (e.PropertyName == TwoLinedButton.TextProperty.PropertyName)
        {
            //Set text block properties
        }
    }