Search This Blog

Friday 27 November 2020

Xamarin Form Custom Loading Bar Control



CustomControl Creation.
LoaderControl.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CustomLoaderControl.CustomControl.LoaderControl">
  <ContentView.Content>
        <StackLayout BackgroundColor="Transparent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
            <ActivityIndicator x:Name="activityIndicator"  IsRunning="True" />
            <Label x:Name="indicatorLabel" VerticalTextAlignment="Center"   FontAttributes="Bold"  HorizontalTextAlignment="Center" Text="Please wait.." />
        </StackLayout>
    </ContentView.Content>
</ContentView>
LoaderControl.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
 
namespace CustomLoaderControl.CustomControl
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoaderControl : ContentView
    {
        #region Indicator Color 
        public static readonly BindableProperty IndicatorColorProperty = BindableProperty.Create(
         propertyName: nameof(IndicatorColor),
         returnType: typeof(Color),
         declaringType: typeof(LoaderControl),
         defaultValue: null,
         defaultBindingMode: BindingMode.TwoWay,
         propertyChanged: IndicatorColorPropertyChanged);
 
        private static void IndicatorColorPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (LoaderControl)bindable;
            if (newValue != null)
            {
                control.activityIndicator.Color = (Color)newValue;
            }
        }
        public Color IndicatorColor
        {
            get => (Color)GetValue(IndicatorColorProperty);
            set { SetValue(IndicatorColorProperty, value); }
        }
        #endregion
 
        #region Indicator Text Color
        public static readonly BindableProperty IndicatorTextColorProperty = BindableProperty.Create(
       propertyName: nameof(IndicatorTextColor),
       returnType: typeof(Color),
       declaringType: typeof(LoaderControl),
       defaultValue: null,
       defaultBindingMode: BindingMode.TwoWay,
       propertyChanged: IndicatorTextColorPropertyChanged);
 
        private static void IndicatorTextColorPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (LoaderControl)bindable;
            if (newValue != null)
            {
                control.indicatorLabel.TextColor = (Color)newValue;
            }
        }
        public Color IndicatorTextColor
        {
            get => (Color)GetValue(IndicatorTextColorProperty);
            set { SetValue(IndicatorTextColorProperty, value); }
        }
        #endregion
 
        #region Indicator Text
        public static readonly BindableProperty IndicatorTextProperty = BindableProperty.Create(
       propertyName: nameof(IndicatorText),
       returnType: typeof(string),
       declaringType: typeof(LoaderControl),
       defaultValue: "Loading",
       defaultBindingMode: BindingMode.TwoWay,
       propertyChanged: IndicatorTextPropertyChanged);
 
        private static void IndicatorTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (LoaderControl)bindable;
            if (newValue != null)
            {
                control.indicatorLabel.Text = (string)newValue;
            }
        }
        public string IndicatorText
        {
            get => (string)GetValue(IndicatorTextProperty);
            set { SetValue(IndicatorTextProperty, value); }
        }
        #endregion
        public LoaderControl()
        {
            InitializeComponent();
        }
    }
}


CustomControl Implementation

MainPage.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:customcontrol="clr-namespace:CustomLoaderControl.CustomControl"
             x:Class="CustomLoaderControl.MainPage">
 
    <StackLayout Spacing="20">
        <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
            <Label Text="Custom Loader Control!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
        </Frame>
        <customcontrol:LoaderControl IndicatorColor="Red" IndicatorTextColor="Black" IndicatorText="Loader1 Loading..." />
        <customcontrol:LoaderControl IndicatorColor="Green" IndicatorTextColor="DarkCyan" IndicatorText="Loader2 Loading..." />
        <customcontrol:LoaderControl IndicatorColor="LightBlue" IndicatorTextColor="Black" IndicatorText="Loader3 Loading..." />
        <customcontrol:LoaderControl IndicatorColor="Gray" IndicatorTextColor="Red" IndicatorText="Loader3 Loading..." />
        <customcontrol:LoaderControl IndicatorColor="Blue" IndicatorTextColor="Black" IndicatorText="Loader3 Loading..." />
    </StackLayout>
</ContentPage>
 


App.xaml.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
 
namespace CustomLoaderControl
{
    public partial class App: Application
    {
        public App()
        {
            InitializeComponent();
 
            MainPage = new MainPage();
        }
 
        protected override void OnStart()
        {
        }
 
        protected override void OnSleep()
        {
        }
 
        protected override void OnResume()
        {
        }
    }
}
 

Thursday 12 November 2020

Xamarin Forms Compile Binding Demo

Compile Time Binding in Content Page & DataTemplate

Views(EmployeePage.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:viewModels="clr-namespace:CompileTimeBinding.ViewModels"
             xmlns:models ="clr-namespace:CompileTimeBinding.Models"
             x:DataType="viewModels:EmployeePageViewModel"
             x:Class="CompileTimeBinding.Views.EmployeePage">
    <ContentPage.BindingContext>
        <viewModels:EmployeePageViewModel />
    </ContentPage.BindingContext>
    <ContentPage.Content>
        <StackLayout Margin="10" >
            <ListView SeparatorVisibility="None" HasUnevenRows="True" ItemsSource="{Binding Employees}" >
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="models:Employee">
                        <ViewCell>
                            <StackLayout Margin="10">
                                <Label >
                                    <Label.FormattedText>
                                        <FormattedString>
                                            <Span Text="{Binding FirstName}" />
                                            <Span Text=" " />
                                            <Span Text="{Binding LastName}" />
                                        </FormattedString>
                                    </Label.FormattedText>
                                </Label>
                                <Label Text="{Binding Email}" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>


EmployeePage.xaml.cs

using CompileTimeBinding.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
 
namespace CompileTimeBinding.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class EmployeePage : ContentPage
    {
        public EmployeePage()
        {
            InitializeComponent();
        }
    }
}


ViewModels (EmployeePageViewModel.cs)

using CompileTimeBinding.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
 
namespace CompileTimeBinding.ViewModels
{
    public class EmployeePageViewModel
    {
        #region Properties
 
        public ObservableCollection<Employee> Employees { get; set; }
 
        #endregion
 
        #region Constructor
        public EmployeePageViewModel()
        {
            Employees = new ObservableCollection<Employee>();
            Employee obj = new Employee();
            obj.FirstName = "Pragnesh";
            obj.LastName = "Mistry";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
            obj = new Employee();
            obj.FirstName = "Vishal";
            obj.LastName = "Makvana";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
            obj = new Employee();
            obj.FirstName = "Nirav";
            obj.LastName = "Tailor";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
 
            obj = new Employee();
            obj.FirstName = "Viral";
            obj.LastName = "Mistry";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
            obj = new Employee();
            obj.FirstName = "Bhavik";
            obj.LastName = "Mistry";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
            obj = new Employee();
            obj.FirstName = "Jignesh";
            obj.LastName = "Tailor";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
            obj = new Employee();
            obj.FirstName = "Sachin";
            obj.LastName = "Shinde";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
 
            obj = new Employee();
            obj.FirstName = "Viral";
            obj.LastName = "Patel";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
 
 
            obj = new Employee();
            obj.FirstName = "Mayur";
            obj.LastName = "Patel";
            obj.Email = "abc@gmail.com";
            Employees.Add(obj);
        }
        #endregion
    }
}
 

Models (Employee.cs)

using System;
using System.Collections.Generic;
using System.Text;
 
namespace CompileTimeBinding.Models
{
    public class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Address { get; set; }
    }
}
 

App.xaml.cs

using CompileTimeBinding.Views;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
 
namespace CompileTimeBinding
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
 
            MainPage = new EmployeePage();
        }
 
        protected override void OnStart()
        {
        }
 
        protected override void OnSleep()
        {
        }
 
        protected override void OnResume()
        {
        }
    }
}
 




Tuesday 10 November 2020

How to Use Relative Source in ListView

TestPage.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:TestApp.ViewModels.TestPageViewModel" 
             x:Class="TestApp.Views.TestPage">
    <ContentPage.Content>
        <StackLayout >
            <ListView  Margin="10,-10,0,0"  HasUnevenRows="True"  SeparatorVisibility="None" ItemsSource="{Binding EmployeeDetails}" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout>
                                <Label Margin="33,0,0,0" Text="{Binding Title}"  TextColor="Gray" />
                                <Label  Margin="33,0,0,0"  TextColor="Gray">
                                    <Label.FormattedText >
                                        <FormattedString  >
                                            <Span Text="{Binding FirstName}" />
                                            <Span Text=" to " />
                                            <Span Text="{Binding LastName}" />
                                        </FormattedString>
                                    </Label.FormattedText>
                                </Label>
                                <StackLayout.GestureRecognizers>
                                    <TapGestureRecognizer CommandParameter="{Binding .}" Command="{Binding Source={RelativeSource AncestorType={x:Type local:TestPageViewModel}},Path=TestCommand}" />
                                </StackLayout.GestureRecognizers>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.Footer>
                    <Label HeightRequest="80" />
                </ListView.Footer>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Thursday 5 November 2020

Borderless Entry Control in Xamarin Forms



Implementation (LoginPage.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:renderer="clr-namespace:TestApp.Renderer"
             x:Class="TestApp.Views.Login.LoginPage">
    <ContentPage.Content>
        <Grid Margin="10,70,10,10" HorizontalOptions="StartAndExpand" VerticalOptions="StartAndExpand">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <renderer:BorderlessEntry Text="This is Borderless entry" Grid.Row="0" />
        </Grid>
    </ContentPage.Content>
</ContentPage>

XamarinForm Renderer (BorderlessEntry.cs)

Create Custom Renderer in your Xamarin Form Project

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
 
namespace TestApp.Renderer
{
    public class BorderlessEntry : Entry
    {
    }
}

Create Platform Specific Renderer for iOS & Android Project that Export  BorderlessEntry.cs Renderer(From Xamarin Form Project)

Xamarin.Android Renderer (BorderlessEntryRenderer.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Text;
using Android.Views;
using Android.Widget;
using TestApp.Droid.CustomRenderers;
using TestApp.Renderer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
 
[assembly: ExportRenderer(typeof(BorderlessEntry), typeof(BorderlessEntryRenderer))]
namespace TestApp.Droid.CustomRenderers
{
    public class BorderlessEntryRenderer : EntryRenderer
    {
        public BorderlessEntryRenderer(Context context):base(context)
        {
 
        }
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (Control != null && Element != null)
            {
                Control.Background = null;
            }
        }
    }
}

Xamarin.ios Renderer (BorderlessEntryRenderer.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestApp.iOS.CustomRenderers;
using TestApp.Renderer;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
 
[assembly: ExportRenderer(typeof(BorderlessEntry), typeof(BorderlessEntryRenderer))]
namespace TestApp.iOS.CustomRenderers
{
    public class BorderlessEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
 
            if (Control != null && Element != null)
            {
                Control.BackgroundColor = Color.Transparent.ToUIColor();
                Control.Layer.BackgroundColor = Color.Transparent.ToCGColor();
                Control.BorderStyle = UITextBorderStyle.None;
            }
        }
    }
}
 

Popular Posts