🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
Xamarin Cross-Platform Development Samples
Xamarin.Forms and Xamarin.Native implementation examples for cross-platform mobile development with C# and .NET
💻 Xamarin.Forms Basic CRUD Operations csharp
🟢 simple
Build a cross-platform mobile app with basic Create, Read, Update, Delete operations using Xamarin.Forms and SQLite
// XAML - 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"
x:Class="XamarinCRUDApp.MainPage"
Title="Contact Manager">
<StackLayout Padding="20" Spacing="10">
<Label Text="Contact Manager"
FontSize="Large"
FontAttributes="Bold"
HorizontalOptions="Center" />
<Entry x:Name="NameEntry" Placeholder="Name" />
<Entry x:Name="EmailEntry" Placeholder="Email" Keyboard="Email" />
<Entry x:Name="PhoneEntry" Placeholder="Phone" Keyboard="Telephone" />
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
<Button Text="Add" Clicked="OnAddClicked" />
<Button Text="Update" Clicked="OnUpdateClicked" />
<Button Text="Delete" Clicked="OnDeleteClicked" />
</StackLayout>
<ListView x:Name="ContactsListView"
ItemSelected="OnContactSelected">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}"
Detail="{Binding Email}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
// C# - Contact.cs
using SQLite;
using System.ComponentModel;
namespace XamarinCRUDApp.Models
{
public class Contact : INotifyPropertyChanged
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
private string _email;
public string Email
{
get => _email;
set
{
_email = value;
OnPropertyChanged(nameof(Email));
}
}
private string _phone;
public string Phone
{
get => _phone;
set
{
_phone = value;
OnPropertyChanged(nameof(Phone));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
// C# - DatabaseService.cs
using SQLite;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using XamarinCRUDApp.Models;
namespace XamarinCRUDApp.Services
{
public class DatabaseService
{
private readonly SQLiteAsyncConnection _database;
public DatabaseService(string dbPath)
{
_database = new SQLiteAsyncConnection(dbPath);
_database.CreateTableAsync<Contact>().Wait();
}
public Task<List<Contact>> GetContactsAsync()
{
return _database.Table<Contact>().ToListAsync();
}
public Task<Contact> GetContactAsync(int id)
{
return _database.Table<Contact>()
.Where(c => c.Id == id)
.FirstOrDefaultAsync();
}
public Task<int> SaveContactAsync(Contact contact)
{
if (contact.Id != 0)
{
return _database.UpdateAsync(contact);
}
else
{
return _database.InsertAsync(contact);
}
}
public Task<int> DeleteContactAsync(Contact contact)
{
return _database.DeleteAsync(contact);
}
}
}
💻 Xamarin.Forms Navigation with MasterDetail Page csharp
🟡 intermediate
Implement advanced navigation patterns using MasterDetail pages with menu navigation, page transitions, and mobile-specific UX patterns
// XAML - AppShell.xaml
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:XamarinNavigationApp.Views"
x:Class="XamarinNavigationApp.AppShell"
FlyoutHeaderBehavior="FlyoutHeaderBehavior.OnScroll">
<Shell.FlyoutHeader>
<Grid BackgroundColor="#2196F3" HeightRequest="150">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0"
Source="appicon.png"
HeightRequest="60"
WidthRequest="60"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Grid.Row="1"
Text="My App"
TextColor="White"
FontSize="Large"
HorizontalTextAlignment="Center" />
</Grid>
</Shell.FlyoutHeader>
<FlyoutItem Title="Home" Icon="home.png">
<ShellContent Route="home" ContentTemplate="{DataTemplate views:HomePage}" />
</FlyoutItem>
<FlyoutItem Title="Products" Icon="products.png">
<TabBar>
<ShellContent Title="All Products" Route="products"
ContentTemplate="{DataTemplate views:ProductsPage}" />
<ShellContent Title="Categories" Route="categories"
ContentTemplate="{DataTemplate views:CategoriesPage}" />
<ShellContent Title="Search" Route="search"
ContentTemplate="{DataTemplate views:SearchPage}" />
</TabBar>
</FlyoutItem>
<FlyoutItem Title="Profile" Icon="profile.png">
<ShellContent Route="profile" ContentTemplate="{DataTemplate views:ProfilePage}" />
</FlyoutItem>
<FlyoutItem Title="Settings" Icon="settings.png">
<ShellContent Route="settings" ContentTemplate="{DataTemplate views:SettingsPage}" />
</FlyoutItem>
<MenuItem Text="Logout" Icon="logout.png" Clicked="OnLogoutClicked" />
</Shell>
// XAML - 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="XamarinNavigationApp.Views.HomePage"
Title="Home">
<RefreshView x:Name="RefreshView" IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}">
<ScrollView>
<StackLayout Padding="20" Spacing="20">
<!-- Welcome Section -->
<Frame BackgroundColor="#2196F3" Padding="20" CornerRadius="10">
<StackLayout>
<Label Text="Welcome Back!"
TextColor="White"
FontSize="24"
FontAttributes="Bold" />
<Label Text="{Binding UserWelcome}"
TextColor="White"
FontSize="16"
Opacity="0.8" />
</StackLayout>
</Frame>
<!-- Quick Actions -->
<Label Text="Quick Actions"
FontSize="18"
FontAttributes="Bold" />
<Grid RowSpacing="15" ColumnSpacing="15">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Frame Grid.Row="0" Grid.Column="0"
BackgroundColor="#FF9800" Padding="20"
HasShadow="True">
<StackLayout>
<Image Source="add.png"
WidthRequest="30"
HeightRequest="30"
HorizontalOptions="Center" />
<Label Text="Add Item"
TextColor="White"
HorizontalTextAlignment="Center"
FontSize="12" />
</StackLayout>
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding AddItemCommand}" />
</Frame.GestureRecognizers>
</Frame>
</Grid>
</StackLayout>
</ScrollView>
</RefreshView>
</ContentPage>
// C# - HomeViewModel.cs
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XamarinNavigationApp.ViewModels
{
public class HomeViewModel : INotifyPropertyChanged
{
private bool _isRefreshing;
private string _userWelcome;
public bool IsRefreshing
{
get => _isRefreshing;
set
{
_isRefreshing = value;
OnPropertyChanged();
}
}
public string UserWelcome
{
get => _userWelcome;
set
{
_userWelcome = value;
OnPropertyChanged();
}
}
public ObservableCollection<RecentActivity> RecentActivities { get; set; }
public Command AddItemCommand { get; }
public Command SearchCommand { get; }
public Command FavoritesCommand { get; }
public Command SettingsCommand { get; }
public Command RefreshCommand { get; }
public HomeViewModel()
{
UserWelcome = "John Doe";
RecentActivities = new ObservableCollection<RecentActivity>();
AddItemCommand = new Command(async () => await Shell.Current.GoToAsync("additem"));
SearchCommand = new Command(async () => await Shell.Current.GoToAsync("search"));
FavoritesCommand = new Command(async () => await Shell.Current.GoToAsync("favorites"));
SettingsCommand = new Command(async () => await Shell.Current.GoToAsync("settings"));
RefreshCommand = new Command(async () => await RefreshData());
LoadRecentActivities();
}
private void LoadRecentActivities()
{
RecentActivities.Clear();
RecentActivities.Add(new RecentActivity
{
Title = "New Product Added",
Description = "Added 'Wireless Headphones' to inventory",
TimeAgo = "2 hours ago",
Icon = "add.png"
});
}
private async Task RefreshData()
{
IsRefreshing = true;
await Task.Delay(2000);
LoadRecentActivities();
IsRefreshing = false;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class RecentActivity
{
public string Title { get; set; }
public string Description { get; set; }
public string TimeAgo { get; set; }
public string Icon { get; set; }
}
}
💻 Xamarin Web API Integration with Authentication csharp
🔴 complex
Build a production-ready Xamarin app with REST API integration, JWT authentication, secure token storage, and offline synchronization
// C# - Models/ApiResponse.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace XamarinAPIClient.Models
{
public class ApiResponse<T>
{
public bool Success { get; set; }
public string Message { get; set; }
public T Data { get; set; }
public List<string> Errors { get; set; } = new List<string>();
}
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; }
}
public class LoginRequest
{
public string Email { get; set; }
public string Password { get; set; }
}
public class LoginResponse
{
public string Token { get; set; }
public DateTime ExpiresAt { get; set; }
public User User { get; set; }
}
}
// C# - Services/ApiService.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using XamarinAPIClient.Helpers;
using XamarinAPIClient.Models;
namespace XamarinAPIClient.Services
{
public class ApiService
{
private readonly HttpClient _httpClient;
private readonly IAuthenticationService _authService;
public ApiService(IAuthenticationService authService)
{
_httpClient = new HttpClient
{
BaseAddress = new Uri(Settings.ApiBaseUrl)
};
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
_authService = authService;
}
private async Task<bool> AddAuthorizationHeaderAsync()
{
var token = await _authService.GetTokenAsync();
if (!string.IsNullOrEmpty(token))
{
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
return true;
}
return false;
}
public async Task<ApiResponse<LoginResponse>> LoginAsync(LoginRequest loginRequest)
{
try
{
var json = JsonConvert.SerializeObject(loginRequest);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("/api/auth/login", content);
var responseContent = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ApiResponse<LoginResponse>>(responseContent);
if (response.IsSuccessStatusCode && result.Success)
{
await _authService.SaveTokenAsync(result.Data.Token, result.Data.ExpiresAt);
await _authService.SaveUserAsync(result.Data.User);
}
return result;
}
catch (Exception ex)
{
return new ApiResponse<LoginResponse>
{
Success = false,
Message = $"Network error: {ex.Message}"
};
}
}
public async Task<ApiResponse<List<Product>>> GetProductsAsync()
{
try
{
if (!await AddAuthorizationHeaderAsync())
{
return new ApiResponse<List<Product>>
{
Success = false,
Message = "Authorization required"
};
}
var response = await _httpClient.GetAsync("/api/products");
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
await _authService.SignOutAsync();
return new ApiResponse<List<Product>>
{
Success = false,
Message = "Session expired. Please login again."
};
}
var responseContent = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ApiResponse<List<Product>>>(responseContent);
return result;
}
catch (Exception ex)
{
return new ApiResponse<List<Product>>
{
Success = false,
Message = $"Network error: {ex.Message}"
};
}
}
}
}
// C# - Services/AuthenticationService.cs
using XamarinAPIClient.Helpers;
using XamarinAPIClient.Models;
using System.Threading.Tasks;
using Plugin.SecureStorage;
namespace XamarinAPIClient.Services
{
public interface IAuthenticationService
{
Task<bool> IsAuthenticatedAsync();
Task<bool> LoginAsync(string email, string password);
Task SignOutAsync();
Task<User> GetCurrentUserAsync();
Task<string> GetTokenAsync();
Task SaveTokenAsync(string token, DateTime expiresAt);
}
public class AuthenticationService : IAuthenticationService
{
private readonly ApiService _apiService;
public AuthenticationService(ApiService apiService)
{
_apiService = apiService;
}
public async Task<bool> IsAuthenticatedAsync()
{
try
{
var token = await GetTokenAsync();
var expiresAt = CrossSecureStorage.Current.GetValue("token_expires");
if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(expiresAt))
return false;
var expiryDate = DateTime.Parse(expiresAt);
// Refresh token if it's expired or about to expire (within 5 minutes)
if (expiryDate < DateTime.UtcNow.AddMinutes(5))
{
var refreshResult = await _apiService.RefreshTokenAsync();
return refreshResult.Success;
}
return true;
}
catch
{
return false;
}
}
public async Task<bool> LoginAsync(string email, string password)
{
try
{
var loginRequest = new LoginRequest
{
Email = email,
Password = password
};
var response = await _apiService.LoginAsync(loginRequest);
return response.Success;
}
catch
{
return false;
}
}
public async Task SignOutAsync()
{
CrossSecureStorage.Current.DeleteKey("auth_token");
CrossSecureStorage.Current.DeleteKey("refresh_token");
CrossSecureStorage.Current.DeleteKey("token_expires");
CrossSecureStorage.Current.DeleteKey("user_data");
}
public async Task<User> GetCurrentUserAsync()
{
try
{
var userData = CrossSecureStorage.Current.GetValue("user_data");
if (!string.IsNullOrEmpty(userData))
{
return JsonConvert.DeserializeObject<User>(userData);
}
}
catch { }
return null;
}
public async Task<string> GetTokenAsync()
{
return await Task.FromResult(
CrossSecureStorage.Current.GetValue("auth_token"));
}
public async Task SaveTokenAsync(string token, DateTime expiresAt)
{
await Task.Run(() =>
{
CrossSecureStorage.Current.SetValue("auth_token", token);
CrossSecureStorage.Current.SetValue("token_expires", expiresAt.ToString());
});
}
}
}