Skip to content

Instantly share code, notes, and snippets.

@johnshew
Last active Mar 5, 2016
Embed
What would you like to do?
GISTS for MVVM UWP with CRUD over a Data Service (Published)
using System.Diagnostics;
namespace Data
{
public class Person
{
public String Name { get; set; }
public int Age { get; set; }
}
public class FakeService
{
public static String Name = "Fake Data Service.";
public static List<Person> GetPeople()
{
Debug.WriteLine("GET for people.");
return new List<Person>()
{
new Person() { Name="Chris Cole", Age=10 },
new Person() { Name="Kelly Kale", Age=32 },
new Person() { Name="Dylan Durbin", Age=18 }
};
}
public static void Write(Person person)
{
Debug.WriteLine("INSERT person with name " + person.Name);
}
public static void Delete(Person person)
{
Debug.WriteLine("DELETE person with name " + person.Name);
}
}
}
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Vertical">
<ListView x:Name="MainList"
ItemsSource="{x:Bind Organization.People, Mode=OneWay}"
SelectedIndex="{x:Bind Organization.SelectedIndex, Mode=TwoWay}"
MinWidth="250" Margin="5">
<ListView.ItemTemplate>
<DataTemplate x:DataType="viewModels:PersonViewModel" >
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Content="Add" Click="{x:Bind Organization.Add}" Margin="5"/>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Vertical">
<TextBox
Text="{x:Bind Organization.SelectedPerson.Name, Mode=TwoWay, FallbackValue=''}"
Margin="5" />
<TextBox
Text="{x:Bind Organization.SelectedPerson.Age, Mode=TwoWay, FallbackValue='0'}"
Margin="5" />
<Button Content="Delete" Click="{x:Bind Organization.Delete}" Margin="5" />
</StackPanel>
</Grid>
using Data;
namespace Models
{
public class Organization
{
public List<Person> People { get; set; }
public String Name { get; set; }
public Organization(String databaseName)
{
Name = databaseName;
People = FakeService.GetPeople();
}
public void Add(Person person) {
if (!People.Contains(person))
{
People.Add(person);
FakeService.Write(person);
}
}
public void Delete(Person person)
{
if (People.Contains(person))
{
People.Remove(person);
FakeService.Delete(person);
}
}
public void Update(Person person)
{
FakeService.Write( person);
}
}
}
using System.ComponentModel;
using System.Collections.ObjectModel;
using Models;
namespace ViewModels
{
public class OrganizationViewModel : NotificationBase
{
Organization organization;
public OrganizationViewModel(String name)
{
organization = new Organization(name);
_SelectedIndex = -1;
// Load the database
foreach (var person in organization.People)
{
var np = new PersonViewModel(person);
np.PropertyChanged += Person_OnNotifyPropertyChanged;
_People.Add(np);
}
}
ObservableCollection<PersonViewModel> _People
= new ObservableCollection<PersonViewModel>();
public ObservableCollection<PersonViewModel> People
{
get { return _People; }
set { SetProperty(ref _People, value); }
}
String _Name;
public String Name
{
get { return organization.Name; }
}
int _SelectedIndex;
public int SelectedIndex
{
get { return _SelectedIndex; }
set { if (SetProperty(ref _SelectedIndex, value))
{ RaisePropertyChanged(nameof(SelectedPerson)); } }
}
public PersonViewModel SelectedPerson
{
get { return (_SelectedIndex >= 0) ? _People[_SelectedIndex] : null; }
}
public void Add()
{
var person = new PersonViewModel();
person.PropertyChanged += Person_OnNotifyPropertyChanged;
People.Add(person);
organization.Add(person);
SelectedIndex = People.IndexOf(person);
}
public void Delete()
{
if (SelectedIndex != -1)
{
var person = People[SelectedIndex];
People.RemoveAt(SelectedIndex);
organization.Delete(person);
}
}
void Person_OnNotifyPropertyChanged(Object sender, PropertyChangedEventArgs e)
{
organization.Update((PersonViewModel)sender);
}
}
}
using Data;
namespace ViewModels
{
public class PersonViewModel : NotificationBase<Person>
{
public PersonViewModel(Person person = null) : base(person) { }
public String Name
{
get { return This.Name; }
set { SetProperty(This.Name, value, () => This.Name = value); }
}
public int Age
{
get { return This.Age; }
set { SetProperty(This.Age, value, () => This.Age = value); }
}
}
}
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ViewModels
{
public class NotificationBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// SetField (Name, value); // where there is a data member
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] String property
= null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
RaisePropertyChanged(property);
return true;
}
// SetField(()=> somewhere.Name = value; somewhere.Name, value)
// Advanced case where you rely on another property
protected bool SetProperty<T>(T currentValue, T newValue, Action DoSet,
[CallerMemberName] String property = null)
{
if (EqualityComparer<T>.Default.Equals(currentValue, newValue)) return false;
DoSet.Invoke();
RaisePropertyChanged(property);
return true;
}
protected void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
public class NotificationBase<T> : NotificationBase where T : class, new()
{
protected T This;
public static implicit operator T(NotificationBase<T> thing) { return thing.This; }
public NotificationBase(T thing = null)
{
This = (thing == null) ? new T() : thing;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment