Skip to content

Instantly share code, notes, and snippets.

@kristijankralj
Last active March 13, 2021 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kristijankralj/8418524e337ea5117869419e28df9658 to your computer and use it in GitHub Desktop.
Save kristijankralj/8418524e337ea5117869419e28df9658 to your computer and use it in GitHub Desktop.
Xamarin.Forms Shell code snippets
using System.Reflection;
using Autofac;
using Xamarin.Forms;
namespace SampleNamespace
{
public partial class App : Application
{
public static IContainer Container;
public App()
{
InitializeComponent();
//class used for registration
var builder = new ContainerBuilder();
//scan and register all classes in the assembly
var dataAccess = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(dataAccess)
.AsImplementedInterfaces()
.AsSelf();
//TODO - register repositories if you use them
//builder.RegisterType<Repository<User>>().As<IRepository<User>>();
//get container
Container = builder.Build();
//set first page
MainPage = Container.Resolve<MainView>();
}
}
}
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace SampleNamespace
{
public abstract class ExtendedBindableObject : BindableObject
{
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;
}
}
public abstract class BaseViewModel : ExtendedBindableObject
{
public virtual Task InitializeAsync(object parameter)
{
return Task.CompletedTask;
}
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set
{
if (SetProperty(ref _isBusy, value))
{
IsNotBusy = !_isBusy;
}
}
}
private bool _isNotBusy = true;
public bool IsNotBusy
{
get => _isNotBusy;
set
{
if (SetProperty(ref _isNotBusy, value))
{
IsBusy = !_isNotBusy;
}
}
}
}
}
using System;
using System.IO;
namespace Cryptollet.Common.Database
{
public static class DatabaseConstants
{
public const string DatabaseFilename = "AppSQLite.db3";
public const SQLite.SQLiteOpenFlags Flags =
// open the database in read/write mode
SQLite.SQLiteOpenFlags.ReadWrite |
// create the database if it doesn't exist
SQLite.SQLiteOpenFlags.Create |
// enable multi-threaded database access
SQLite.SQLiteOpenFlags.SharedCache;
public static string DatabasePath
{
get
{
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(basePath, DatabaseFilename);
}
}
}
}
using System.Threading.Tasks;
using Xamarin.Forms;
namespace SampleNamespace
{
public interface IDialogMessage
{
Task DisplayAlert(string title, string message, string cancel);
Task<bool> DisplayAlert(string title, string message, string accept, string cancel);
Task<string> DisplayPrompt(string title, string message, string accept, string cancel);
Task<string> DisplayActionSheet(string title, string destruction, params string[] buttons);
}
public class DialogMessage : IDialogMessage
{
public async Task DisplayAlert(string title, string message, string cancel)
{
await Shell.Current.DisplayAlert(title, message, cancel);
}
public Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
{
return Shell.Current.DisplayAlert(title, message, accept, cancel);
}
public Task<string> DisplayPrompt(string title, string message, string accept, string cancel)
{
return Shell.Current.DisplayPromptAsync(title, message, accept, cancel);
}
public Task<string> DisplayActionSheet(string title, string destruction, params string[] buttons)
{
return Shell.Current.DisplayActionSheet(title, "Cancel", destruction, buttons);
}
}
}
using System.Text.RegularExpressions;
namespace SampleNamespace
{
public class EmailRule<T> : IValidationRule<T>
{
public string ValidationMessage { get; set; }
public bool Check(T value)
{
if (value == null)
{
return false;
}
var str = value as string;
Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
Match match = regex.Match(str);
return match.Success;
}
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Xamarin.Forms;
namespace SampleNamespace
{
public class FirstValidationErrorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ICollection<string> errors = value as ICollection<string>;
return errors != null && errors.Count > 0 ? errors.ElementAt(0) : null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
namespace SampleNamespace
{
public class IsNotNullOrEmptyRule<T> : IValidationRule<T>
{
public string ValidationMessage { get; set; }
public bool Check(T value)
{
if (value == null)
{
return false;
}
var str = value as string;
return !string.IsNullOrWhiteSpace(str);
}
}
}
using System;
namespace SampleNamespace
{
public interface IValidationRule<T>
{
string ValidationMessage { get; set; }
bool Check(T value);
}
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SampleNamespace
{
public interface INetworkService
{
Task<TResult> GetAsync<TResult>(string uri);
Task<TResult> PostAsync<TResult>(string uri, string jsonData);
Task<TResult> PutAsync<TResult>(string uri, string jsonData);
Task DeleteAsync(string uri);
}
public class NetworkService : INetworkService
{
private HttpClient _httpClient;
public NetworkService()
{
_httpClient = new HttpClient();
}
public async Task<TResult> GetAsync<TResult>(string uri)
{
HttpResponseMessage response = await _httpClient.GetAsync(uri);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = JsonConvert.DeserializeObject<TResult>(serialized);
return result;
}
public async Task<TResult> PostAsync<TResult>(string uri, string jsonData)
{
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.PostAsync(uri, content);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = JsonConvert.DeserializeObject<TResult>(serialized);
return result;
}
public async Task<TResult> PutAsync<TResult>(string uri, string jsonData)
{
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.PutAsync(uri, content);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = JsonConvert.DeserializeObject<TResult>(serialized);
return result;
}
public async Task DeleteAsync(string uri)
{
await _httpClient.DeleteAsync(uri);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cryptollet.Common.Extensions;
using SQLite;
namespace SampleNamespace
{
public interface IDatabaseItem
{
int Id { get; set; }
}
public abstract class BaseDatabaseItem: IDatabaseItem
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
}
public interface IRepository<T> where T : IDatabaseItem, new()
{
Task<T> GetById(int id);
Task<int> DeleteAsync(T item);
Task<List<T>> GetAllAsync();
Task<int> SaveAsync(T item);
}
public class Repository<T> : IRepository<T> where T : IDatabaseItem, new()
{
readonly Lazy<SQLiteAsyncConnection> lazyInitializer = new Lazy<SQLiteAsyncConnection>(() =>
{
return new SQLiteAsyncConnection(DatabaseConstants.DatabasePath, DatabaseConstants.Flags);
});
private SQLiteAsyncConnection Database => lazyInitializer.Value;
public Repository()
{
InitializeAsync().SafeFireAndForget(false);
}
async Task InitializeAsync()
{
if (!Database.TableMappings.Any(m => m.MappedType.Name == typeof(T).Name))
{
await Database.CreateTableAsync(typeof(T)).ConfigureAwait(false);
}
}
public Task<T> GetById(int id)
{
return Database.Table<T>().Where(x => x.Id == id).FirstOrDefaultAsync();
}
public Task<int> DeleteAsync(T item)
{
return Database.DeleteAsync(item);
}
public Task<List<T>> GetAllAsync()
{
return Database.Table<T>().ToListAsync();
}
public Task<int> SaveAsync(T item)
{
if (item.Id != 0)
{
return Database.UpdateAsync(item);
}
else
{
return Database.InsertAsync(item);
}
}
}
}
using System.Threading.Tasks;
using Cryptollet.Common.Base;
using Xamarin.Forms;
namespace Cryptollet.Common.Navigation
{
public interface INavigationService
{
Task PushAsync<TViewModel>(string parameters = null) where TViewModel : BaseViewModel;
Task PopAsync();
Task InsertAsRoot<TViewModel>(string parameters = null) where TViewModel : BaseViewModel;
Task GoBackAsync();
}
public class ShellRoutingService: INavigationService
{
public Task PopAsync()
{
return Shell.Current.Navigation.PopAsync();
}
public Task GoBackAsync()
{
return Shell.Current.GoToAsync("..");
}
public Task InsertAsRoot<TViewModel>(string parameters = null) where TViewModel : BaseViewModel
{
return GoToAsync<TViewModel>("//", parameters);
}
public Task PushAsync<TViewModel>(string parameters = null) where TViewModel : BaseViewModel
{
return GoToAsync<TViewModel>("", parameters);
}
private Task GoToAsync<TViewModel>(string routePrefix, string parameters) where TViewModel : BaseViewModel
{
var route = routePrefix + typeof(TViewModel).Name;
if (!string.IsNullOrWhiteSpace(parameters))
{
route += $"?{parameters}";
}
return Shell.Current.GoToAsync(route);
}
}
}
using System;
using System.Threading.Tasks;
namespace SampleNamespace
{
public static class TaskExtensions
{
// NOTE: Async void is intentional here. This provides a way
// to call an async method from the constructor while
// communicating intent to fire and forget, and allow
// handling of exceptions
public static async void SafeFireAndForget(this Task task,
bool returnToCallingContext,
Action<Exception> onException = null)
{
try
{
await task.ConfigureAwait(returnToCallingContext);
}
// if the provided action is not null, catch and
// pass the thrown exception
catch (Exception ex) when (onException != null)
{
onException(ex);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace SampleNamespace
{
//ExtendedBindableObject is in BaseViewModel.cs
public class ValidatableObject<T> : ExtendedBindableObject
{
public List<IValidationRule<T>> Validations { get; }
private List<string> _errors;
public List<string> Errors
{
get => _errors;
set { SetProperty(ref _errors, value); }
}
private T _value;
public T Value
{
get => _value;
set { SetProperty(ref _value, value); }
}
private bool _isValid;
public bool IsValid
{
get => _isValid;
set { SetProperty(ref _isValid, value); }
}
public ValidatableObject()
{
_isValid = true;
_errors = new List<string>();
Validations = new List<IValidationRule<T>>();
}
public bool Validate()
{
Errors.Clear();
IEnumerable<string> errors = Validations.Where(v => !v.Check(Value))
.Select(v => v.ValidationMessage);
Errors = errors.ToList();
IsValid = !Errors.Any();
return IsValid;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment