hlbmallo
hlbmallo

Reputation: 151

RadioGroup in Xamarin Forms Native Views

I have the following lines of XAML that utilises Native Views in Xamarin Forms:

        <androidWidget:RadioGroup x:Arguments="{x:Static formsAndroid:Forms.Context}">
            <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Click="RadioButton1Clicked"/>
            <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Click="RadioButton2Clicked"/>
            <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Click="RadioButton3Clicked"/>
            <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Click="RadioButton4Clicked"/>
        </androidWidget:RadioGroup>

However, the following exception is thrown: "Can not set the content of androidWidget:RadioGroup as it doesn't have a ContentPropertyAttribute"

Just wondering if anyone could help me find the correct XAML layout for the RadioGroup in relation to the RadioButtons?

Cheers

Upvotes: 0

Views: 1025

Answers (1)

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10831

However, the following exception is thrown: "Can not set the content of androidWidget:RadioGroup as it doesn't have a ContentPropertyAttribute"

Not all native views can be used in xaml directly. RadioGroup is one of them.

To use it in your Xaml, you need to follow the below steps:

  1. In YourProject.Droid create a custom RadioGroup control:

    public class MyRadioGroup:RadioGroup
    {
        //Every native control in xaml will be wrapped in NativeViewWrapper, so we want to pass a NativeViewWrapper list here
        IList<NativeViewWrapper> items;
        public IList<NativeViewWrapper> ItemsSource
        {
            get {
                items.Clear();
                for (int i = 0; i < this.ChildCount; i++)
                {
                    items.Add(new NativeViewWrapper(this.GetChildAt(i)));
                }
                return items;
            }
            set {
                //xaml compiler will call this setter
                if (items != value)
                {
                    items = value;
                    this.RemoveAllViews();
                    foreach (NativeViewWrapper wrapper in items)
                    {
                        this.AddView(wrapper.NativeView);
                    }
                }
            }
        }
        public MyRadioGroup(Context context) : base(context)
        {
            items = new List<NativeViewWrapper>();
        }
    }
    
  2. In your pcl library add necessary namespaces:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            ...
            xmlns:androidWrapper="clr-namespace:Xamarin.Forms.Platform.Android;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"
            xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
            xmlns:androidLocal="clr-namespace:NativeSwitch.Droid;assembly=NativeSwitch.Droid;targetPlatform=Android"
            xmlns:formsAndroid="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"
    xmlns:local="clr-namespace:NativeSwitch"
    ...">
    
  3. Reference the custom MyRadioGroup in your xaml page:

    <StackLayout Margin="20">
        <androidLocal:MyRadioGroup x:Arguments="{x:Static formsAndroid:Forms.Context}" >
            <androidLocal:MyRadioGroup.ItemsSource>
                <x:Array Type="{x:Type androidWrapper:NativeViewWrapper}">
                    <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Text="Scale1" />
                    <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Text="Scale2" />
                    <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Text="Scale3" />
                    <androidWidget:RadioButton x:Arguments="{x:Static formsAndroid:Forms.Context}" Text="Scale4" />
                </x:Array>
            </androidLocal:MyRadioGroup.ItemsSource>
        </androidLocal:MyRadioGroup>
    </StackLayout>
    

You can find a complete demo here.

For similar official tutorial, please refer to Subclassing Native Views

For passing arguments inside Xaml, please refer to Passing Arguments in Xaml

Upvotes: 3

Related Questions