Skip to content

Instantly share code, notes, and snippets.

@ghuntley
Created August 27, 2019 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghuntley/45938a7d64f54fea974bb27fd92cd291 to your computer and use it in GitHub Desktop.
Save ghuntley/45938a7d64f54fea974bb27fd92cd291 to your computer and use it in GitHub Desktop.
example of todomvc as mvvm w/redux via Uno.CodeGen
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using TodoApp.Shared.Models;
namespace TodoApp.Shared.ViewModels
{
public class MainPageViewModel : INotifyPropertyChanged
{
private string _newTodoText;
private State _state = State.Default;
private int _filter = 0;
public MainPageViewModel()
{
CreateNew = new SimpleCommand(ExecuteCreateNew);
ViewAll = new SimpleCommand(() => Filter = 0);
ViewActive = new SimpleCommand(() => Filter = 1);
ViewInactive = new SimpleCommand(() => Filter = 2);
}
public State State
{
get => _state;
private set
{
_state = value;
OnPropertyChanged();
OnPropertyChanged(nameof(Todos));
}
}
public int Filter
{
get => _filter;
set
{
_filter = value;
OnPropertyChanged();
OnPropertyChanged(nameof(Todos));
}
} // 0-all, 1-active, 2-inactives
public IEnumerable<Todo> Todos
{
get
{
switch (Filter)
{
case 0:
return _state.Todos;
case 1:
return _state.ActiveTodos;
case 2:
return _state.InactiveTodos;
}
throw new InvalidOperationException();
}
}
public string NewTodoText
{
get => _newTodoText;
set
{
_newTodoText = value;
OnPropertyChanged();
}
}
public ICommand CreateNew { get; }
public ICommand ViewAll { get; }
public ICommand ViewActive { get; }
public ICommand ViewInactive { get; }
private void ExecuteCreateNew()
{
var newTodo = new Todo(NewTodoText);
State = State.WithTodos(todos => todos.Add(newTodo));
NewTodoText = "";
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void ChangeState(Todo todo, bool isDone)
{
State = State.WithTodos(todos =>
{
var existing = todos.FirstOrDefault(t => t.KeyEquals(todo));
Todo newTodo = existing.WithIsDone(isDone);
return newTodo != existing ? todos.Replace(existing, newTodo) : todos;
});
}
public void ChangeText(Todo todo, string newText)
{
State = State.WithTodos(todos =>
{
var existing = todos.FirstOrDefault(t => t.KeyEquals(todo));
Todo newTodo = existing.WithText(newText);
return newTodo != existing ? todos.Replace(existing, newTodo) : todos;
});
}
public void RemoveTodo(Todo todo)
{
State = State.WithTodos(todos =>
{
var existing = todos.FirstOrDefault(t => t.KeyEquals(todo));
return existing != null ? todos.Remove(existing) : todos;
});
}
}
}
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Uno;
namespace TodoApp.Shared.Models
{
[GeneratedImmutable]
public partial class State
{
[EqualityHash]
public ImmutableArray<Todo> Todos { get; } = ImmutableArray<Todo>.Empty;
[EqualityIgnore]
public int RemainingTodos => ActiveTodos.Count();
[EqualityIgnore]
public IEnumerable<Todo> ActiveTodos => Todos.Where(t => !t.IsDone);
[EqualityIgnore]
public IEnumerable<Todo> InactiveTodos => Todos.Where(t => t.IsDone);
}
}
using System;
using System.Threading;
using Uno;
namespace TodoApp.Shared.Models
{
[GeneratedImmutable]
public partial class Todo
{
public Todo(string text)
{
Text = text;
}
[EqualityKey]
public Guid Id { get; } = Guid.NewGuid();
public bool IsDone { get; }
public string Text { get; }
}
}
@ghuntley
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment