Home > OS >  Does a custom renderer not work when it is used inside a data template within the resource dictionar
Does a custom renderer not work when it is used inside a data template within the resource dictionar

Time:05-17

I am trying to make a chat page where the messages are arranged from the left side(conversee) or right side(user). So, I will be using a data template selector and a listview/collection view to hold the messages. Everything works fine if I use the default "Label" view, but if I change it to my own custom "Label" renderer, it does not work anymore.

Here is my code for the custom "Label" renderer.

CustomLabel.cs in shared folder

public class CustomLabel : Label
{
    public static readonly BindableProperty MaxWidthProperty = BindableProperty.Create(nameof(MaxWidth), typeof(int), typeof(CustomLabel));
    public int MaxWidth
    {
        get { return (int)GetValue(MaxWidthProperty); }
        set { SetValue(MaxWidthProperty, value); }
    }
}

CustomLabelRenderer.cs in Android

public class CustomLabelRenderer : LabelRenderer
{
    public CustomLabelRenderer(Context context) : base(context)
    {
        AutoPackage = false;
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        if(Context != null)
        {
            var view = ((CustomLabel)Element);
            Control.SetMaxWidth(view.MaxWidth);
        }
    }
}

Here is my code for the datatemplate selector within the resource dictionary and pictures of the result. For using the custom label, I just substituted "Label" with "local:CustomLabel".

Using Label

<ResourceDictionary>
        <DataTemplate x:Key="leftSideTemplate" x:DataType="model:Message">
            <ViewCell>
                <Label Text="{Binding Text}"
                        HorizontalTextAlignment="Start"
                        HorizontalOptions="StartAndExpand" 
                        BackgroundColor="{StaticResource BgColorSecondaryUser}"/>
            </ViewCell>
        </DataTemplate>
        <DataTemplate x:Key="rightSideTemplate" x:DataType="model:Message">
            <ViewCell>
                <Label Text="{Binding Text}"
                        HorizontalTextAlignment="End"
                        HorizontalOptions="EndAndExpand" 
                        BackgroundColor="{StaticResource BgColorPrimaryUser}"/>
            </ViewCell>
        </DataTemplate>
        <dt:ConversationTemplateSelector x:Key="conversationPageTemplateSelector"
            LeftSideTemplate="{StaticResource leftSideTemplate}" RightSideTemplate="{StaticResource rightSideTemplate}"/>
    </ResourceDictionary>

Using default "Label" view

Using my custom "Label" renderer

CodePudding user response:

Only SetMaxWidth when view's MaxWidth property is greater than 0. Otherwise, the control may have zero width, so nothing is seen:

    if (view.MaxWidth > 0)
        Control.SetMaxWidth(view.MaxWidth);
  • Related