Monday 29 October 2018

Segmented Control in Xamarin.Forms

Introduction

In this article, we are going to create segment control in xamarin.forms. Segmented Control is a horizontal bar, which is made up of multiple segments. Each segment works as a discrete button and it can display a title or an image. 

Use of SegmentControl:
Segmented Control is used when you want to show/ hide data based on the selected category in the same view. For example, you want to display different lists in the same ListView based on the segment selected.
Let’s create a simple app in which the color of the view changes based on the selected segment from SegmentedControl.
Requirements:
  • This article source code is prepared by using Visual Studio 2017. And it is better to install the latest visual studio updates from here.
  • This article is prepared on a MAC machine.
  • This sample project is Xamarin.Forms .Net standard project.
  • This sample app is targeted for Android, iOS. And tested for Android & iOS.
Description:

The creation of  Xamarin.Forms project is very simple in Visual Studio for Mac. It will creates three projects 
1) Shared Code
2) Xamarin.Android
3) Xamarin.iOS
Because Mac system with  Visual Studio for Mac it doesn't support Windows projects(UWP, Windows, Windows Phone)
The following steps will show you how to create Xamarin.Forms project in Mac system with  Visual Studio,
First, open the Visual Studio for Mac. And Click on New Project 


After that, we need to select whether you're doing Xamarin.Forms or Xamarin.Android or Xamarin.iOS project. if we want to create Xamarin.Forms project just follow the below screenshot.

Give the App Name i.e XFSegmentControlDemo.

Note: 
In the above screen under Shared Code, select use .NET Standard or Use Shared Library. Then click on Next Button and below screenshot will show you how to browse to save the project on our PC.


After click on Create, button it will create the XFSegmentControlDemo Xamarin.Forms project like below
  • XFSegmentControlDemo: It is for Shared Code
  • XFSegmentControlDemo.Droid: It is for Android.
  • XFSegmentControlDemo.iOS: It is for iOS

We need to follow below few steps to create segment control 
.Net Standard/PCL:
Step 1:
First, we need to add the Plugin.SegmentedControl.Netstandard plugin on all platforms through nuget.
Right, click on Packages->AddPackages

Now, Search plugin with Plugin.Segmented name.


Step 1:
Create your own Xaml page named HomePage.xaml, and make sure to refer "Plugin.Segmented.Control" class in Xaml by declaring a namespace and using the namespace prefix we can renderer the segment contol. The following code example shows how the Plugin.Segmented.Control plugin renderer class can be consumed by a Xaml page:
HomePage.xaml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.     xmlns:control="clr-namespace:Plugin.Segmented.Control;assembly=Plugin.Segmented"
  5.     xmlns:iOSForms="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"   
  6.     iOSForms:Page.UseSafeArea="true"  
  7.     xmlns:local="clr-namespace:XFSegmentControlDemo" x:Class="XFSegmentControlDemo.Views.HomePage">  
  8.     <StackLayout VerticalOptions="FillAndExpand" Padding="30" Spacing="20">  
  9.          <Label Text="SegmentContol" FontSize="30" TextColor="Maroon" HorizontalOptions="CenterAndExpand" />  
  10.         <control:SegmentedControl x:Name="SegmentedControl"  
  11.             SelectedSegment="{Binding SegmentSelection}"  
  12.             TintColor="BlueViolet"  
  13.             SelectedTextColor="White"  
  14.             DisabledColor="Gray"  
  15.             Margin="8,8,8,8">  
  16.             <control:SegmentedControl.Children>  
  17.                 <control:SegmentedControlOption Text="Item 1"/>  
  18.                 <control:SegmentedControlOption Text="Item 2"/>  
  19.                 <control:SegmentedControlOption Text="Item 3"/>  
  20.                 <control:SegmentedControlOption Text="Item 4"/>  
  21.             </control:SegmentedControl.Children>  
  22.         </control:SegmentedControl>  
  23.         <Label Text="{Binding SelectedSegment}" FontSize="40" TextColor="Maroon" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>  
  24.     </StackLayout>  
  25. </ContentPage>  
  
Note:
The "control" namespace prefix can be named anything. However, the clr-namespace and assembly values must match the details of the custom renderer class. Once the namespace is declared the prefix is used to reference the segment control.

Make BindingContext in code behind with HomePageViewModel.
HomePage.xaml.cs
  1. using Plugin.Segmented.Control;  
  2. using Plugin.Segmented.Event;  
  3. using Xamarin.Forms;  
  4. using XFSegmentControlDemo.ViewModels;  
  5.   
  6. namespace XFSegmentControlDemo.Views  
  7. {  
  8.     public partial class HomePage : ContentPage  
  9.     {  
  10.         HomePageViewModel _homePageViewModel;  
  11.         public HomePage()  
  12.         {  
  13.             InitializeComponent();  
  14.   
  15.             _homePageViewModel = new HomePageViewModel();  
  16.   
  17.             BindingContext = _homePageViewModel;  
  18.   
  19.             SegmentedControl.OnSegmentSelected += (object sender, SegmentSelectEventArgs e) => {  
  20.                 var selectedSegment = ((SegmentedControl)sender).SelectedSegment;  
  21.                 _homePageViewModel.SelectedSegment = selectedSegment;  
  22.             };  
  23.         }  
  24.     }  
  25. }  
ViewModels:
HomePageViewModel.cs

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Runtime.CompilerServices;  
  5.   
  6. namespace XFSegmentControlDemo.ViewModels  
  7. {  
  8.     public class HomePageViewModel : INotifyPropertyChanged  
  9.     {  
  10.   
  11.         int _selectedSegement;  
  12.   
  13.         public int SelectedSegment {  
  14.   
  15.             get { return _selectedSegement; }  
  16.             set {  
  17.                 _selectedSegement = value;  
  18.                 switch (SelectedSegment) {  
  19.                     case 0:  
  20.   
  21.                         break;  
  22.                     case 1:  
  23.                          
  24.                         break;  
  25.                     case 2:  
  26.                         
  27.                         break;  
  28.                     case 3:  
  29.                           
  30.                         break;  
  31.                 }  
  32.                 OnPropertyChanged("SelectedSegment");  
  33.             }  
  34.         }  
  35.   
  36.         protected bool SetProperty<T>(ref T backingStore, T value,  
  37.            [CallerMemberName]string propertyName = "",  
  38.            Action onChanged = null) {  
  39.             if (EqualityComparer<T>.Default.Equals(backingStore, value))  
  40.                 return false;  
  41.             backingStore = value;  
  42.             onChanged?.Invoke();  
  43.             OnPropertyChanged(propertyName);  
  44.             return true;  
  45.         }  
  46.   
  47.         //INotifyPropertyChanged implementation method  
  48.         public event PropertyChangedEventHandler PropertyChanged;  
  49.         protected void OnPropertyChanged([CallerMemberName] string propertyName = "") {  
  50.             var changed = PropertyChanged;  
  51.             if (changed == null)  
  52.                 return;  
  53.             changed.Invoke(thisnew PropertyChangedEventArgs(propertyName));  
  54.         }  
  55.     }  
  56. }     

Here, SelectedSegment property will get the selected segment index.

AppDelegate.cs
In AppDelegate we should initializer segementcontrolrenderer like below.
  1. using System;    
  2. using System.Collections.Generic;    
  3. using System.Linq;    
  4. using Foundation;    
  5. using Plugin.Segmented.Control.iOS;    
  6. using UIKit;    
  7.     
  8. namespace XFSegmentControlDemo.iOS    
  9. {    
  10.     [Register("AppDelegate")]    
  11.     public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate    
  12.     {    
  13.         public override bool FinishedLaunching(UIApplication app, NSDictionary options)    
  14.         {    
  15.             global::Xamarin.Forms.Forms.Init();    
  16.     
  17.             SegmentedControlRenderer.Initialize();    
  18.     
  19.             LoadApplication(new App());    
  20.     
  21.             return base.FinishedLaunching(app, options);    
  22.         }    
  23.     }    
  24.   

Output:



Please download the source code from below.

No comments:

Post a Comment