Giter Club home page Giter Club logo

bindery's Introduction

Bindery

Bindery aims to support fluent MVVM binding definition for WinForms applications.

Projects

  • Bindery:
    • Contains the static Create factory class
    • Dependent on the System.Reactive package
    • Please note that it may be necessary to install the System.Reactive.Compatibility package in the main project of a consuming application in order to resolve conflicts between the System.Reactive package and older versions of System.Reactive-related libraries (such as Sytem.Reactive.Linq).

Assumptions

  • A View Model is a binding source, an object of any type. Full binding functionality requires a View Model to properly implement INotifyPropertyChanged.
  • A Control is a binding target, an object that implements IBindableComponent. A Control supports the full range of binding functionality.
  • A Target is a binding target, an object of any type. A Target only supports a limited set of binding functionality.
  • A Command is an object that implements ICommand.

Code Examples

Binding

Create a root binder for the view model
var binder = Bindery.Create.Binder(viewModel);
Create a root binder and set the default subscription scheduler to schedule actions on the form's thread
var binder = Bindery.Create.Binder(viewModel, new ControlScheduler(form));
Dispose of a binder

Diposing of a binder removes all bindings and disposes of all subcriptions created by the binder.

binder.Dispose();
Register external disposables with the binder

This can be used to tie the lifetime of other objects to the binder's lifetime.

binder.RegisterDisposable(disposableViewModel, disposableCommand);
Bind a view model property to a control property
// Two-way binding
binder.Control(textBox).Property(c => c.Text).Bind(vm => vm.Name); 
// One-way binding from source to control
binder.Control(form).Property(c => c.UseWaitCursor).Get(vm => vm.IsBusy); 
// One-way binding from control to source
binder.Control(textBox).Property(c => c.Text).Set(vm => vm.Name); 
Bind an integer view model property to a string control property
binder.Control(textBox).Property(c => c.Text).Get(vm => vm.Age, Convert.ToString);
Bind a button's Click event to a command

This also "binds" the control's Enabled property to the command's CanExecute method.

ICommand command = new CommandImplementation(viewModel);
binder.Control(button).OnClick(command);
Bind a form's MouseMove event to a command
ICommand command = new CommandImplementation(viewModel);
binder.Control(form).OnEvent<MouseEventArgs>("MouseMove")
  .Transform(o => o.Where(ctx => ctx.Args.Button==MouseButtons.Left).Select(ctx => new {ctx.Args.X, ctx.Args.Y})) 
  // Mouse coords are passed to command.Execute()
  .Execute(command);
Bind a form's MouseMove event arguments to a view model property
binder.Control(form).OnEvent<MouseEventArgs>("MouseMove")
  .Transform(o => o.Select(ctx => new MyCoord{X = ctx.Args.X, Y = ctx.Args.Y}))
  .Set(vm => vm.CurrentMouseCoords);
Bind to a non-control target object

Non-control targets support a limited set of binding options. Two-way binding and one-way binding from target to source are not supported.

binder.Target(target).Property(t => t.Status).Get(vm => vm.Status);

Observable subscriptions

Trigger an action when a view model property changes
binder.OnPropertyChanged(vm => vm.ErrorMessage).Subscribe(msg => DisplayErrorDialog(msg));
Subscribe to a button's Click event to close the form
binder.Control(cancelButton).OnClick().Subscribe(ctx => form.Close());
Subscribe to a form's Closed event to dispose of the binder
binder.Control(form).OnEvent("Closed").Subscribe(ctx => binder.Dispose());
Create an observable subscription to execute a command
binder.Observe(viewModel.Observable).Execute(command);
Overriding the default scheduler to execute the command immediately on each observed object
binder.Observe(viewModel.Observable).ObserveOn(Scheduler.Immediate).Execute(command);
Subscribe to an observable with full subscription syntax support
binder.Observe(viewModel.Observable).Subscribe(
  ctx=>ctx.OnNext(oVal => OnNextAction(oVal))
       .OnError(ex => HandleException(ex))
       .OnComplete(() => OnCompleteAction()));
Create an observable subscription to call an async method
binder.Observe(viewModel.Observable).SubscribeAsync(msg => command.ExecuteAsync(msg.Value));

Event to observable conversion

IObservable<string> mouseMoveButtons =
  Bindery.Create.ObservableFor(form).Event<MouseEventArgs>("MouseMove")
       .Select(ctx => Convert.ToString(ctx.Args.Button));

bindery's People

Contributors

slugburn avatar kshanafelt avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.