Skip to content

Instantly share code, notes, and snippets.

@NVentimiglia
Last active August 11, 2016 23:20
Show Gist options
  • Save NVentimiglia/3b0e651d2a902fa722d516e06e8c2c60 to your computer and use it in GitHub Desktop.
Save NVentimiglia/3b0e651d2a902fa722d516e06e8c2c60 to your computer and use it in GitHub Desktop.
using System;
namespace Framework.Observables
{
/// <summary>
/// Microsoft Style MVVM
/// </summary>
/// <remarks>
/// Pros :
/// - Standardized and tested
/// - No Unity Code (testable)
/// Cons :
/// - Inheritance
/// - Poor support for 'cs views' (string key comparison)
/// - get/set can be optional (if binding is oneway to source or one time)
/// </remarks>
public class ObservableObject : IPropertyChanged
{
public event PropertyChanged OnPropertyChanged = delegate { };
public virtual void RaisePropertyChanged(string propertyName)
{
OnPropertyChanged(propertyName);
}
}
/// <summary>
/// Microsoft Style MVVM
/// </summary>
public class MicrosoftViewModel : ObservableObject
{
private string _userName;
public string UserName
{
get { return _userName; }
set
{
if (value == _userName)
return;
_userName = value;
RaisePropertyChange("UserName");
}
}
private string _password;
public string Password
{
get { return _password; }
set
{
if (value == _password)
return;
_password = value;
RaisePropertyChange("Password");
}
}
[Import]
IAccountService accounts;
public void SignIn()
{
//Call Service / Controller Here
accounts.SignIn(UsernName, Password);
}
}
/// <summary>
/// Lorenzo Style MVVM
/// </summary>
/// <remarks>
/// Pros :
/// - No Inheritance
/// - No PropertyName key comparison
/// - Support for databinding
/// - Support for 'cs views'
/// - No Unity Code (testable)
/// Cons :
/// - Unstandardized, will need to refactor binders
/// Notes :
/// - Observable<> can be optional (if binding is oneway to source or one time)
/// </remarks>
public class Observable<T>
{
public event Action<T> OnChange = delegate { };
private T _value;
public T Value
{
get { return _value; }
set
{
if (Equals(value, Value))
return;
_value = value;
RaiseChanged();
}
}
public virtual void RaiseChanged()
{
OnChange(Value);
}
//TODO Equals override, json support, Misc C# stuff
}
/// <summary>
/// Lorenzo Style MVVM
/// </summary>
public class LorenzoViewModel
{
public Observable<string> UserName = new Observable<string>();
public Observable<string> Password = new Observable<string>();
public Observable<bool> IsBusy = new Observable<bool>();
[Import]
IAccountService accounts;
public void SignIn()
{
//Call Service / Controller Here
accounts.SignIn(UsernName, Password);
}
}
/// <summary>
/// Lorenzo Style MVVM for lazy people
/// </summary>
public class VentiViewModel
{
// AccountModel is a simple 'dto' with a username and password.
// View has a single event it listens to and does a batch redraw of all fields
public Observable<AccountModel> Model = new Observable<AccountModel>();
[Import]
IAccountService accounts;
public void SignIn()
{
//Call Service / Controller Here
accounts.SignIn(Model);
}
/// <summary>
/// Raising View Navigation for discussion.
/// Frankly, navigation is a little wierd with MVVM as we will want to navigate to/from a viewmodel
/// </summary>
public class VentiViewModel2
{
public Observable<AccountModel> Model = new Observable<AccountModel>();
public Observable<bool> IsBusy = new Observable<bool>();
[Import]
IAccountService accounts;
[Import]
INavigationService navigation;
public void SignIn()
{
IsBusy.Value = true;
//Call Service / Controller Here
ResponseModel response = await accounts.SignIn(Model);
IsBusy.Value = false;
if(response.IsError)
{
//Show a view as a temporary popup
await navigation.ShowPopupAsync(new ErrorViewModel(response.ErrorMessage));
}
else
{
//Present a new view
navigation.PushView(new MainViewModel());
}
}
public void Back()
{
// Back to previous page in the navigational stack
navigation.PopAsync();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment