Apply Custom Renderer Without ExportRenderer Attribute

The normal way to apply a platform specific custom renderer is like this:

[assembly: ExportRenderer(typeof(PlatformSpecificContentPage), typeof(UWPContentPageRenderer))]

This blanket affects all classes of type PlatformSpecificContentPage in the system. But, I want to be able to apply a custom renderer to say "Entry" controls through Xaml. e.g. in some cases, I want to replace an TextBox in UWP with a custom control that has syntax highlighting, but not in all cases. The problem with the ExportRendererAttribute is that I have to inherit from Entry in order to apply the custom renderer. This is a pretty silly design flaw of the system.

Best Answer

Answers

  • Gigex42Gigex42 USMember ✭✭✭✭
    edited June 2017

    You can create a class within pcl project inheriting from your control. Then in the platform specific custom renderer you type in the first typeof() the class you created. Then you can differ from the two conrols within you xaml.

    Hope this helps.

  • JohnHJohnH GBMember ✭✭✭✭✭

    @MelbourneDeveloper I disagree with it being a design flaw. Create your Entry descendant and apply the renderer. If you only want the renderer for some entry instances either only use the descendant when you need it, or always use it and then add a bindable boolean property to your descendant that the renderer will consider. Its not rocket science.

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    edited June 2017

    @JohnHair said:
    @MelbourneDeveloper I disagree with it being a design flaw. Create your Entry descendant and apply the renderer. If you only want the renderer for some entry instances either only use the descendant when you need it, or always use it and then add a bindable boolean property to your descendant that the renderer will consider. Its not rocket science.

    It is a design flaw. What you have suggested will obviously work because this is how the system is designed.

    My question though, is is it possible to apply a custom renderer via XAML, not through an Attribute?

  • Gigex42Gigex42 USMember ✭✭✭✭

    I dont think this works with XAML.

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭

    Can this be confirmed?

    If not, why not?

  • Gigex42Gigex42 USMember ✭✭✭✭

    Never seen anything like renderer in xaml. You also need some logic in your renderer which cannot be handled in xaml.

    Also why would you need it in xaml?

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    Accepted Answer

    It seems that the answer is no.

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    edited June 2017

    For the record, it would be useful to be able to selectively apply a custom renderer at the XAML level because

    a) We shouldn't need to inherit from a class in order to be able to apply a custom renderer. It just creates pointless extra code.

    b) We may only want to apply custom renderers to some instances of the class - not all.

    This is just common sense.

  • Gigex42Gigex42 USMember ✭✭✭✭

    @MelbourneDeveloper said:
    For the record, it would be useful to be able to selectively apply a custom renderer at the XAML level because

    a) We shouldn't need to inherit from a class in order to be able to apply a custom renderer. It just creates pointless extra code.

    b) We may only want to apply custom renderers to some instances of the class - not all.

    This is just common sense.

    a) We do need because we need the base of that control.
    b) You can like I already said..

    If you create a renderer class in your Droid project like this

    `
    [assembly: ExportRenderer(typeof(EntryFocus), typeof(EntryFocusRenderer))]
    namespace AAA.Droid.CustomRenderer
    {
    public class EntryFocusRenderer : EntryRenderer
    {
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);

            if (Control != null)
            {
                SetNativeControl(Control);
                Control.SetSelectAllOnFocus(true);
            }
        }
    }
    

    }`

    The important part is the typeof(EntryFocus).

    This is just an empty class in my pcl project inheriting from Entry.
    public class EntryFocus : Entry
    {
    }

    In your XAML:
    xmlns:cr="clr-namespace:AAA.CustomRenderer"
    ...
    You can now use Entry or EntryFocus as a control. First one is the standard and the other you custom control.

Sign In or Register to comment.