Skip to content

Parametric/Bindery

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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));

About

Fluent MVVM binding for WinForms

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages