Search This Blog

Sunday 29 May 2022

Setting Application Theme Manually In .Net MAUI

 Write Following code on App.xaml.cs

namespace CustomRenderer;
 
public partial class App : Application
{
	public App()
	{
		InitializeComponent();
                Application.Current.UserAppTheme = AppTheme.Light;
                MainPage = new AppShell();
	}
}
 

Thursday 26 May 2022

How To Access Android Context In Xamarin Forms

Write the Following Code In the Android Class of the Android Project.

var context = Android.App.Application.Context;

How to Integrate Firebase Crashlytics and Firebase Analytic In Your Xamarin Project

Firebase Crashlytics And Analytic Configuration For Android


Add Application in Google Firebase Console.
Create New Project in Google Firebase Console. Then Select Project Overview Option.

Click on +Add App Option & Select Android Project.

Add your Android Project Package Name here and then click on Register App.
Note: You will get the package name from the AndroidManifest.xml file.


Google-Service.json download this JSON file.
























Now Add this JSON file to your Android Project.















Now Right-click on the google-service.json file and Select Properties Option.















Select BuildAction : GoogleServiceJson
Copy to Output Directory: Do not copy.

Note: If you are not able to see GoogleServiceJson Build Action, Then Install the Following Plugin in your Android Project.
Xamarin.GooglePlayServices.Base
Xamarin.Google.Dagger

Xamarin.Anroid
Install the Following Plugin in your Xamarin Android Project.

Xamarin.Firebase.Analytics









Xamarin.Firebase.Crashlytics












Now Create a strings.xml file into the Resources/values folder of your Xamarin Android Project.

Add the following code in the strings.xml file
<?xml version="1.0" encoding="utf-8" ?>
<resources>
	<string name="com.google.firebase.crashlytics.mapping_file_id">none</string>
</resources>
 

Add this line in the OnCreate method of the MainActivity.cs file to send an unsent report of errors.
    Firebase.Crashlytics.FirebaseCrashlytics.Instance.SendUnsentReports();




All setup for android is done.


Firebase Crashlytics And Analytic Configuration For iOS

Create New Project in Google Firebase Console.
Then Select Project Overview Option.


Click on +Add App Option & Select iOS Project.





































Add your iOS Project Bundle Identifier here and then click on Register App.
You will get the Bundle Identifier from the Info.plist file.

Download GoogleService-Info.plist file and add this file to your Xamarin iOS Project.


Now Add this GoogleService-Info.plist file to your ios Project.



Select BuildAction: BundleResource
Copy to Output Directory: Do not copy.


Xamarin.iOS
Install the Following Plugin in your Xamarin iOS Project.

Xamarin.Firebase.iOS.Analytics










Xamarin.Firebase.iOS.Crashlytics











Now Initialize Firebase Services on AppDelegate.cs file

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
      global::Xamarin.Forms.Forms.Init();
      LoadApplication(new App());
 
      Firebase.Core.App.Configure();
      return base.FinishedLaunching(app, options);
}

All set up for iOS is done.

Now, You Can see Analytic Details & Crashes Detail on Firebase Console/Analytic, Firebase Console/Crashlytics Option.












Tuesday 24 May 2022

Implementing Pull To Refresh With Collection View In .NET MAUI (MVVM)


Youtube: https://youtu.be/XBuSVcBdYo4

Refresh View: Add any view Inside Refresh View to achieve pull to refresh functionality. Let's go through the following examples.


Model:
Employee.cs
namespace MauiApp1.Models
{
    public class Employee
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string Email { get; set; }
    }
}
 
Views:
EmployeeListView.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.Views.EmployeeListView"
             xmlns:viewModels="clr-namespace:MauiApp1.ViewModels"
             xmlns:models="clr-namespace:MauiApp1.Models"
             x:DataType="viewModels:EmployeeListViewModel"
             Title="Employee List">
    <ContentPage.BindingContext>
        <viewModels:EmployeeListViewModel />
    </ContentPage.BindingContext>
    <StackLayout Margin="10">
        <ActivityIndicator IsRunning="True" IsVisible="{Binding IsBusy}" HeightRequest="50" WidthRequest="50" HorizontalOptions="Center" />
        <RefreshView Command="{Binding PullToRefreshCommand}" IsRefreshing="{Binding IsRefreshing}">
            <CollectionView ItemsSource="{Binding Employees}" >
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="models:Employee">
                        <Grid RowDefinitions="5,Auto,5,1">
                            <StackLayout Grid.Row="1">
                                <Label Text="{Binding Name}" FontSize="18" FontAttributes="Bold" />
                                <Label Text="{Binding Email}" FontSize="16"  />
                                <Label Text="{Binding Address}" FontSize="16"  />
                            </StackLayout>
                            <BoxView Grid.Row="3" HeightRequest="1" BackgroundColor="Gray" />
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </RefreshView>
    </StackLayout>
</ContentPage>
 
ViewModels:
BaseViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
 
namespace MauiApp1.ViewModels
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        private bool _isBusy;
        public bool IsBusy
        {
            get => _isBusy;
            set => SetProperty(ref _isBusy, value);
        }
 
        private bool _isRefreshing;
        public bool IsRefreshing
        {
            get => _isRefreshing;
            set => SetProperty(ref _isRefreshing, value);
        }
 
        protected bool SetProperty<T>(ref T backingStore, T value,
       [CallerMemberName] string propertyName = "",
       Action onChanged = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
                return false;
 
            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }
 
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;
            if (changed == null)
                return;
 
            changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
 
EmployeeListViewModel.cs
using MauiApp1.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
 
namespace MauiApp1.ViewModels
{
    public class EmployeeListViewModel : BaseViewModel
    {
        #region Properties
        public ObservableCollection<Employee> Employees { get; set; } = new ObservableCollection<Employee>();
        #endregion
 
 
        #region Constructor
        public EmployeeListViewModel()
        {
            AddDummyEmployeeList();
        }
        #endregion
 
        #region Methods
        private async void AddDummyEmployeeList()
        {
            IsBusy = true;
            await Task.Delay(500); // Write api call here and add that in list
            Employees.Clear();
            Employees.Add(new Employee { Name = "Pragnesh Mistry", Email = "test@gmail.com", Address = "India" });
            Employees.Add(new Employee { Name = "Janani", Email = "abc@gmail.com", Address = "India" });
            Employees.Add(new Employee { Name = "Rahul", Email = "xyz@gmail.com", Address = "India" });
            Employees.Add(new Employee { Name = "Ankit", Email = "test@gmail.com", Address = "India" });
            Employees.Add(new Employee { Name = "Vijay", Email = "test@gmail.com", Address = "India" });
            Employees.Add(new Employee { Name = "Jay", Email = "test@gmail.com", Address = "India" });
            IsBusy = false;
        }
        #endregion
 
 
        #region Commands
        public ICommand PullToRefreshCommand => new Command(() =>
        {
            IsRefreshing = false;
            AddDummyEmployeeList();
        });
        #endregion
 
 
    }
}
 


On App Start Navigate to EmployeeListView Page.
App.xaml.cs
using MauiApp1.Views;
 
namespace MauiApp1;
 
public partial class App: Application
{
    public App()
    {
	InitializeComponent();

        MainPage = new NavigationPage( new EmployeeListView());     } }  


Monday 23 May 2022

How to display PopupPage In .NET MAUI / Xamarin (PushModalAsync)


 





Create a BasePopupPage Control In Your .NET MAUI Project.

BasePopupPage: these controls have default UI and one bindable property called PopupContent that you can use on any Page. I designed BasePopupPage UI as per my requirement you can modify it as per your usage.

BasePopupPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.Controls.BasePopupPage"
             x:Name="this"
             Title="BasePopupPage" >
    <ContentPage.Content>
        <StackLayout   VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
            <Frame VerticalOptions="EndAndExpand" CornerRadius="20" BackgroundColor="White">
                <StackLayout Padding="5,0,5,50"  >
                    <StackLayout  Padding="0,0,0,15">
                        <BoxView  BackgroundColor="LightGray" CornerRadius="5" WidthRequest="100" HeightRequest="10" />
                        <StackLayout.GestureRecognizers>
                            <SwipeGestureRecognizer  Command="{Binding Source={x:Reference this},Path=PopModelCommand}" Threshold="15" Direction="Down" />
                        </StackLayout.GestureRecognizers>
                    </StackLayout>
                    <ContentView   x:Name="ContentView"  />
                </StackLayout>
            </Frame>
            <StackLayout.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding Source={x:Reference this},Path=PopModelCommand}" />
            </StackLayout.GestureRecognizers>
        </StackLayout>
    </ContentPage.Content>
 
</ContentPage>
 

BasePopupPage.xaml.cs
using System.Windows.Input;
 
namespace MauiApp1.Controls;
 
public partial class BasePopupPage : ContentPage
{
    public BasePopupPage()
    {
        InitializeComponent();
        this.BackgroundColor = Color.FromArgb("#80000000");
    }
 
    public static  readonly BindableProperty PopupContentProperty = BindableProperty.Create(
        propertyName: nameof(PopupContent),
        returnType: typeof(View),
        declaringType: typeof(BasePopupPage),
        defaultValue: null,
        defaultBindingMode: BindingMode.OneWay,
        propertyChanged: PopupContentPropertyChanged);
 
    private static void PopupContentPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var controls = (BasePopupPage)bindable;
        if (newValue != null)
            controls.ContentView.Content = (View)newValue;
    }
 
    public  View PopupContent
    {
        get => (View)GetValue(PopupContentProperty);
        set { SetValue(PopupContentProperty, value); }
    }
 
    public ICommand PopModelCommand => new Command(async() =>
    {
        await App.Current.MainPage.Navigation.PopModalAsync();
    });
}


How To Use BasePopupPage.
PopupPage1.xaml
<?xml version="1.0" encoding="utf-8" ?>
<controls:BasePopupPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:controls="clr-namespace:MauiApp1.Controls"
    x:Class="MauiApp1.Views.PopupPage1">
    <controls:BasePopupPage.PopupContent>
        <StackLayout Spacing="15">
                <Label Text="Select An Option" FontSize="16" FontAttributes="Bold"   TextColor="Black"/>
 
                <Label Text="Navigate To Other Popup Page" >
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_NavigateToPoupPage1" />
                    </Label.GestureRecognizers>
                </Label>
                <BoxView BackgroundColor="Black" HeightRequest="1" />
                <Label Text="Navigate to Page" >
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_NavigateToNormalPage" />
                    </Label.GestureRecognizers>
                </Label>
                <BoxView BackgroundColor="Black" HeightRequest="1" />
            </StackLayout>
        </controls:BasePopupPage.PopupContent>
 </controls:BasePopupPage>
 
PopupPage.xaml.cs
using MauiApp1.Controls;
 
namespace MauiApp1.Views;
 
public partial class PopupPage1 : BasePopupPage
{
    public PopupPage1()
    {
        InitializeComponent();
    }
 
    private async void TapGestureRecognizer_Tapped_NavigateToPoupPage1(object sender, EventArgs e)
    {
        await App.Current.MainPage.Navigation.PushModalAsync(new PopupPage2());
    }
 
    private async void TapGestureRecognizer_Tapped_NavigateToNormalPage(object sender, EventArgs e)
    {
        await App.Current.MainPage.Navigation.PopModalAsync();
        await App.Current.MainPage.Navigation.PushAsync(new NewPage1());
    }
 
}

PopupPage2.xaml
<?xml version="1.0" encoding="utf-8" ?>
<controls:BasePopupPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:MauiApp1.Controls"
    x:Class="MauiApp1.Views.PopupPage2" >
    <controls:BasePopupPage.PopupContent>
        <StackLayout Spacing="15">
            <Label Text="Display Content Here" FontSize="16" FontAttributes="Bold"   TextColor="Black"/>
 
        </StackLayout>
    </controls:BasePopupPage.PopupContent>
</controls:BasePopupPage>
 

PopupPage2.xaml.cs
using MauiApp1.Controls;
 
namespace MauiApp1.Views;
 
public partial class PopupPage2 : BasePopupPage
{
    public PopupPage2()
    {
        InitializeComponent();
    }
}

Navigate To Main Page On App Start.
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.MainPage" Title="Main Page">
 
    <StackLayout 
            Spacing="25" 
            VerticalOptions="Center">
 
        <Button Text="Display PoupPage"
                Clicked="Button_Clicked" HorizontalOptions="Center" />
 
    </StackLayout>
 
</ContentPage>
 
MainPage.xaml.cs
using MauiApp1.Views;
 
namespace MauiApp1;
 
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
 
    private async void Button_Clicked(object sender, EventArgs e)
    {
        await App.Current.MainPage.Navigation.PushModalAsync(new PopupPage1());
    }
}
 
 








Popular Posts