Forum Xamarin.Forms

How to get value of custom control's bindable property from custom renderer?

VictorNguyenVictorNguyen USMember ✭✭
edited September 2016 in Xamarin.Forms

I'm still learning how to write a custom control using custom renderer. Right now I'm stuck at getting the value of a bindable property in a custom control from a custom renderer. Could someone help me with this?
Thanks

Custom Control for TimePicker:

public class CustomTimePicker: TimePicker
{
    public static readonly BindableProperty CustomFontSizeProperty =
        BindableProperty.Create("CustomFontSize", typeof(string), typeof (CustomTimePicker), defaultBindingMode: BindingMode.OneWay);
}

Custom Renderer for TimePicker:

[assembly: ExportRenderer(typeof(CustomTimePicker), typeof(CustomTimePickerRenderer))]
namespace MYNS.Mobile.Droid
{
    public class CustomTimePickerRenderer : TimePickerRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e) {
            base.OnElementChanged(e);
            if (e.OldElement == null) {
                Control.SetTextSize(Android.Util.ComplexUnitType.Sp, 11.0f); 
                // right now the font size is hard coded. Id like to get the value from the custom control somehow. 
                // I tried Element but the property is not exposed via that
            }
        }
    }
} 

Best Answers

  • DavidDancyDavidDancy AU ✭✭✭✭
    Accepted Answer

    @VictorNguyen Is that all the code in your custom object? If so, you haven't finished the property.

    If you look in the Xamarin Forms source, you'll see that every BindableProperty has an actual property to match it.

    So in addition to what you have, you also need

    public string CustomFontSize {
        get { return (string) GetValue(CustomFontSizeProperty); }
        set { SetValue(CustomFontSizeProperty, value; }
    }
    

    Then you will be able to refer to Element.CustomFontSize in your renderers.

  • SapienDeveloperSapienDeveloper US ✭✭
    Accepted Answer

    Create a property on your custom control which can retrieve the value from the BindableProperty

    like

    public bool CustomFontSize  
    {
        get { return (string) GetValue(CustomFontSizeProperty);  }
        set { SetValue(CustomFontSizeProperty, value); }
    }
    

    then you should be able to access that from the Renderer like so:

    public class CustomTimePickerRenderer : TimePickerRenderer
    {
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e) 
            {
                base.OnElementChanged(e);
                if(e.NewElement == null) return;
    
                var customPicker = e.NewElement as CustomTimePicker;
    
                //access the CustomFontSize property    
                //customPicker.CustomFontSize
            }
     }
    

Answers

  • DavidDancyDavidDancy AUMember ✭✭✭✭
    Accepted Answer

    @VictorNguyen Is that all the code in your custom object? If so, you haven't finished the property.

    If you look in the Xamarin Forms source, you'll see that every BindableProperty has an actual property to match it.

    So in addition to what you have, you also need

    public string CustomFontSize {
        get { return (string) GetValue(CustomFontSizeProperty); }
        set { SetValue(CustomFontSizeProperty, value; }
    }
    

    Then you will be able to refer to Element.CustomFontSize in your renderers.

  • SapienDeveloperSapienDeveloper USMember ✭✭
    Accepted Answer

    Create a property on your custom control which can retrieve the value from the BindableProperty

    like

    public bool CustomFontSize  
    {
        get { return (string) GetValue(CustomFontSizeProperty);  }
        set { SetValue(CustomFontSizeProperty, value); }
    }
    

    then you should be able to access that from the Renderer like so:

    public class CustomTimePickerRenderer : TimePickerRenderer
    {
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e) 
            {
                base.OnElementChanged(e);
                if(e.NewElement == null) return;
    
                var customPicker = e.NewElement as CustomTimePicker;
    
                //access the CustomFontSize property    
                //customPicker.CustomFontSize
            }
     }
    
  • lucidBrotlucidBrot Member ✭✭

    For me it was enough to cast Element in the custom renderer to MyClass and then access the property without making it bindable. MyClass would in your case beCustomTimePicker`

    Renderer:

    using System;
    using Xamarin.Forms;
    using MyApp.Utils.Views;
    using System.ComponentModel;
    using MyApp.Droid.Renderers;
    using MyApp.UI.Utils.Views;
    using Android.Content;
    using Xamarin.Forms.Platform.Android;
    
    [assembly: ExportRenderer(typeof(MyView), typeof(MyRenderer))]
    namespace Myapp.Droid.Renderers
    {
        public class MyRenderer : Xamarin.Forms.Platform.Android.ScrollViewRenderer
        {
            public MyRenderer(Context context):base(context)
            {
    
            }
    
            protected override void OnElementChanged(VisualElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement as MyView == null)
                    return;
    
                OverScrollMode = ((MyView)e.NewElement).IsOverScrollEnabledOnAndroid ?
                    Android.Views.OverScrollMode.IfContentScrolls :
                    Android.Views.OverScrollMode.Never;
            }
    
        }
    }
    

    Codebehind:

    using System;
    
    using Xamarin.Forms;
    
    namespace MyApp.UI.Utils.Views
    {
        /// <summary>
        /// ScrollView with custom renderer(s).
        /// On Android, disables the blue indication on overScroll
        /// </summary>
        public class MyView : ScrollView
        {
            public bool IsOverScrollEnabledOnAndroid { get; set; }
        }
    }
    
Sign In or Register to comment.