Home > database >  Create re-usable RadioButtonGroupView control
Create re-usable RadioButtonGroupView control

Time:01-19

I have managed to get a radio button group functionality working with the following XAML:

<ScrollView>
    <ListView ItemsSource="{Binding Devices}"
              Style="{StaticResource ListViewSimpleStyle}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell x:DataType="local:DeviceEntryModel">
                    <RadioButton IsChecked="{Binding IsChecked, Mode=TwoWay}"
                                 GroupName="Devices">
                        <RadioButton.Content>
                            <Label BindingContext="{Binding Source={RelativeSource AncestorType={x:Type RadioButton}}, Path=BindingContext}"
                                   Text="{Binding Name}"
                                   IsEnabled="{Binding Source={RelativeSource AncestorType={x:Type RadioButton}}, Path=IsEnabled}" />
                        </RadioButton.Content>
                    </RadioButton>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ScrollView>

Is there any way to simplify this and make it more re-usable? I was thinking of and end result that looks like this:

<RadioButtonGroupView ItemSource="{Binding Devices}">
    <RadioButtonGroupView.ItemTemplate>
      <RadioButton IsChecked="{Binding IsChecked, Mode=TwoWay}"
                   x:DataType="local:Device"
                   GroupName="Devices">
            <Label BindingContext="{Binding Source={RelativeSource AncestorType={x:Type RadioButton}}, Path=BindingContext}"
                   Text="{Binding Name}"
                   IsEnabled="{Binding Source={RelativeSource AncestorType={x:Type RadioButton}}, Path=IsEnabled}" />
        </RadioButton>
    </RadioButtonGroupView.ItemTemplate>
</RadioButtonGroupView>

Something along those lines, something simpler, you get the gist. Thanks!

I tried something with bindable properties but not sure it's the right approach.

CodePudding user response:

Yes, if you want to reuse the control, you can create a ContentView with relative BindableProperty.

Here is a sample code:

ChildView.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiContentViewApp.ChildView"
             x:Name="TestControlView"
             >
    <VerticalStackLayout>
        <Label   Text="{Binding Source={x:Reference TestControlView}, Path=YourName}"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />


        <ListView ItemsSource="{Binding Source={x:Reference TestControlView}, Path=myViewModel.Items }" HasUnevenRows="True" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text="{Binding FileName}" TextColor="#f35e20"  VerticalOptions="Center"/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </VerticalStackLayout>
</ContentView>

ChildView.xaml.cs

public partial class ChildView : ContentView 
{
    public String YourName
    {
        get
        {
            String value = (String)GetValue(YourNameProperty);
            return value;
        }
        set
        {
            SetValue(YourNameProperty, value);
        }
    }

    public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
    , typeof(String)
    , typeof(ChildView), defaultBindingMode: BindingMode.TwoWay, propertyChanged: OnYourNameChanged);

    static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
    {
        Console.WriteLine("-----------------> "   newValue);
    }


    //add MyViewModelProperty
    public static readonly BindableProperty myViewModelProperty =
        BindableProperty.Create(
            nameof(myViewModel),
            typeof(MyViewModel),
            typeof(ChildView),
            null);

    public MyViewModel myViewModel
    {
        set { SetValue(myViewModelProperty, value); }
        get { return (MyViewModel)GetValue(myViewModelProperty); }
    }


    public ChildView()
      {
            InitializeComponent();
      }
}

For more details, you can check thread I want to bind data From two different views.

You can check document BindableProperty for more information.

CodePudding user response:

You need XAML and .CS parts.

In the XAML you define your ControlTemplate. Put everything UI there, and either use TemplatedParent as source or specify that you use TemplateBinding.

In the .CS, you create the core of your control, inheriting ContentView, and writing all BindableProperties that you have been using in the XAML. (I assume Value and ItemSource will be your minimum).

However, I want you to think for a second. IF your model is "Device", how reusable your control should be? If you have, for example, a popup that lets you pick from list of Devices, in most cases the Popup is your reusable part, not the radio button group.

Just something to think about, when you make design choices. Nothing is stopping you from making custom controls, however.

  • Related