Forum Xamarin.Forms

Control Template with two pickers events handle

Hello,
I have below control template in App.xaml & attached screen shots,

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.App">
    <Application.Resources>
        <ResourceDictionary>
            <ControlTemplate x:Key="ActiveProfileTemplate">
                <Grid Padding="5,0,0,0" BackgroundColor="#f7f6fb">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="0.1*" />
                        <RowDefinition Height="0.8*" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <BoxView Grid.ColumnSpan="2"/>
                    <Picker x:Name="FirstPicker" Title="FirstPicker" SelectedIndex="{TemplateBinding Parent.FirstPickerSelectedIndex}" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="180" FontSize="Small" TextColor="#214189">
                        <Picker.Items>
                            <x:String>FirstPicker_1</x:String>
                            <x:String>FirstPicker_2</x:String>
                            <x:String>FirstPicker_3</x:String>
                            <x:String>FirstPicker_4</x:String>
                            <x:String>FirstPicker_5</x:String>
                        </Picker.Items>
                    </Picker>
                    <Picker x:Name="SecondPicker" Title="SecondPicker" SelectedIndex="{TemplateBinding Parent.SecondPickerSelectedIndex}" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="210" FontSize="Small" TextColor="#214189" >
                        <Picker.Items>
                            <x:String>SecondPicker_1</x:String>
                            <x:String>SecondPicker_2</x:String>
                            <x:String>SecondPicker_3</x:String>
                            <x:String>SecondPicker_4</x:String>
                            <x:String>SecondPicker_5</x:String>
                        </Picker.Items>
                    </Picker>
                    <ContentPresenter Grid.Row="1" Grid.ColumnSpan="2"/>
                </Grid>
            </ControlTemplate>
        </ResourceDictionary>
    </Application.Resources>
</Application>

I use that template in two pages: "HomePage" , "DetailPage"
HomePage.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.HomePage">
    <ContentView x:Name="contentView" Padding="0,20,0,0" ControlTemplate="{StaticResource ActiveProfileTemplate}">
        <StackLayout VerticalOptions="CenterAndExpand">
            <Label Text="Welcome to the HomePage!" HorizontalOptions="Center" />
            <Label x:Name="lbl_firstpicker" Text="First Picker Selected Item" HorizontalOptions="Center" TextColor="DarkRed"/>
            <Label x:Name="lbl_secondpicker" Text="Second Picker Selected Item" HorizontalOptions="Center" TextColor="DarkRed"/>
        </StackLayout>
    </ContentView>
</ContentPage>

HomePage.cs

 public partial class HomePage : ContentPage
    {
        public static readonly BindableProperty FirstPickerSelectedIndexProperty = BindableProperty.Create(
            "FirstPickerSelectedIndex",
            typeof(int),
            typeof(HomePage),
            2);
        public static readonly BindableProperty SecondPickerSelectedIndexProperty = BindableProperty.Create(
            "SecondPickerSelectedIndex",
            typeof(int),
            typeof(HomePage),
            3);

        public int FirstPickerSelectedIndex => (int)GetValue(FirstPickerSelectedIndexProperty);
        public int SecondPickerSelectedIndex => (int)GetValue(SecondPickerSelectedIndexProperty);

        public HomePage()
        {
                InitializeComponent();
         }
    }

DetailPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SimpleTheme.DetailPage">
    <ContentView x:Name="contentView" Padding="0,20,0,0" ControlTemplate="{StaticResource ActiveProfileTemplate}">
        <StackLayout VerticalOptions="CenterAndExpand">
            <Label Text="Welcome to the DetailPage!" HorizontalOptions="Center" />
            <Label x:Name="lbl_firstpicker" Text="First Picker Selected Item" HorizontalOptions="Center" TextColor="Teal" />
            <Label x:Name="lbl_secondpicker" Text="Second Picker Selected Item" HorizontalOptions="Center" TextColor="Teal" />
        </StackLayout>
    </ContentView>
</ContentPage>

My questions:

  • How to maintain pickers selected index across all pages that use this template.
  • How to handle selectedindexchange event for both pickers across all pages, ex: (When index change set lbl_firstpicker text with selected text)
    PS: my pickers items sources will be set at run-time from my model. and based on 1st picker selection item source for 2nd picker will change.

regards,
Ahmed

Best Answer

Answers

  • atarekatarek Member ✭✭

    Hello,
    Thanks @yelinzh for you proposed approach.
    When i try to add the above approach in a project contains a Master Page and call MessagingCenter.Send in protected override void OnDisappearing() in view instead of Button_Clicked i face a weird behavior:
    In ContactsPage Choose from first picker DescPl and from second picker SecondModelPl2 then navigate to ReminderPage selected index of second picker will be 0 instead of 1 and this behavior is reproducible by different ways.
    All code is same as above and below code
    Any advice.

    MasterPage.xaml

        <?xml version="1.0" encoding="UTF-8"?>
        <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     xmlns:local="clr-namespace:MasterDetailPageNavigation"
                     x:Class="MasterDetailPageNavigation.MasterPage"
                     Padding="0,40,0,0"
                     Icon="hamburger.png"
                     Title="Personal Organiser">
            <StackLayout BackgroundColor="AliceBlue">
                <ListView x:Name="listView" x:FieldModifier="public">
                    <ListView.Header>
                        <StackLayout Orientation="Horizontal" HeightRequest="150" Spacing="15" Padding="25,0,0,0" >
                            <Label x:Name="contactName" Text="Helloo" LineBreakMode="WordWrap" FontSize="Medium" HorizontalOptions="Start" VerticalOptions="Center"/>
                        </StackLayout>
                    </ListView.Header>
                    <ListView.ItemsSource>
                        <x:Array Type="{x:Type local:MasterPageItem}">
                            <local:MasterPageItem Title="Contacts" IconSource="contacts.png" TargetType="{x:Type local:ContactsPage}" />
                            <local:MasterPageItem Title="TodoList" IconSource="todo.png" TargetType="{x:Type local:TodoListPage}" />
                            <local:MasterPageItem Title="Reminders" IconSource="reminders.png" TargetType="{x:Type local:ReminderPage}" />
                        </x:Array>
                    </ListView.ItemsSource>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Grid Padding="5,10">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="30"/>
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
                                    <Image Source="{Binding IconSource}" />
                                    <Label Grid.Column="1" Text="{Binding Title}" />
                                </Grid>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </ContentPage>
    

    MainPage.xaml

      <?xml version="1.0" encoding="UTF-8"?>
        <MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" 
                          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
                          xmlns:local="clr-namespace:MasterDetailPageNavigation;assembly=MasterDetailPageNavigation"
                          x:Class="MasterDetailPageNavigation.MainPage">
          <MasterDetailPage.Master>
            <local:MasterPage x:Name="masterPage" />
          </MasterDetailPage.Master>
            <MasterDetailPage.Detail>
                <NavigationPage>
                    <x:Arguments>
                        <local:ContactsPage />
                    </x:Arguments>
                </NavigationPage>
            </MasterDetailPage.Detail>
        </MasterDetailPage>
    

    MainPage.cs

    public partial class MainPage : MasterDetailPage
            {
                public MainPage()
                {
                    InitializeComponent();
    
                    masterPage.listView.ItemSelected += OnItemSelected;
    
                    if (Device.RuntimePlatform == Device.UWP)
                    {
                        MasterBehavior = MasterBehavior.Popover;
                    }
                }
    
                private void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
                {
                    if (e.SelectedItem is MasterPageItem item)
                    {
                        Detail = new NavigationPage((Page)Activator.CreateInstance(item.TargetType));
                        masterPage.listView.SelectedItem = null;
                        IsPresented = false;
                    }
                }
            }
        }
    

    ContactPage.cs

      public partial class ContactsPage : ContentPage
        {
            private int firstSelectedIndex;
            private int secondSelectedIndex;
    
            public ContactsPage()
            {
                InitializeComponent();
                //find the picker control and set listener
                Picker p = mv.FindByName<Picker>("FirstPicker");
                Picker s = mv.FindByName<Picker>("SecondPicker");
                p.SelectedIndexChanged += FirstPicker_SelectedIndexChanged;
                s.SelectedIndexChanged += SecondPicker_SelectedIndexChanged;
            }
    
            private void FirstPicker_SelectedIndexChanged(object sender, EventArgs e)
            {
                Picker picker = (Picker)sender;
                firstSelectedIndex = picker.SelectedIndex;
                if (firstSelectedIndex != -1)
                {
                    lbl_firstpicker.Text = picker.Items[firstSelectedIndex];
                }
    
            }
    
            private void SecondPicker_SelectedIndexChanged(object sender, EventArgs e)
            {
                Picker picker = (Picker)sender;
                secondSelectedIndex = picker.SelectedIndex;
    
                if (secondSelectedIndex != -1)
                {
                    lbl_secondpicker.Text = picker.Items[secondSelectedIndex];
                }
            }
    
            protected override void OnDisappearing()
            {
                base.OnDisappearing();
                MessagingCenter.Send<string, int>("firstpicker", "indext", firstSelectedIndex);
                MessagingCenter.Send<string, int>("secondpicker", "indext", secondSelectedIndex);
            }
        }
    

    Regards,
    Ahmed

Sign In or Register to comment.