After coding some pretty interesting new features, as well as to update to the
latest released version of Rx (2.01), I am now releasing a preview release of
ReactiveUI 4.0. You can get the binaries one of two ways:
A few types have been renamed from 3.x (`IViewForViewModel` => `IViewFor`), a
few deprecated methods have been removed (CollectionExtensions), and the
biggest one is that NLog is now optional - if you want to use it, make sure to
install the `reactiveui-nlog` package (it comes by default in the reactiveui
metapackage)
### WhenAny now works with any object!
WhenAny and ObservableForProperty now work with *any* .NET object. The runtime
will detect what kind of object it is (DependencyObject, INPC, etc) and will
determine how to get notifications from it. Note that if you use WhenAny with
an object that doesn't notify (like a regular .NET object), it will warn you
on the logger that changes won't be reported. This framework is extensible as
well, so on MonoMac for example, notifications for NSObjects will be derived
using Key-Value Observing (KVO).
This means that the old `ObservableForDP` method is now deprecated - use
WhenAny instead.
### View Bindings: A Compelling Replacement for XAML bindings
There are currently two methods that are used in the XAML world for binding
Views to ViewModels. The original method, XAML Bindings (i.e. {Binding Foo}),
is quite flexible, but a frustrating aspect of it is that Bindings that are
incorrect, due to typos or other mistakes, don't generate errors - you only
see the error in the trace output. The Binding syntax can also get quite
verbose, and isn't always easy to verify because paths are relative to the
"nearest" DataContext set.
Caliburn Micro decided to take a different approach, with their
"Convention-Based Wireup" - this approach decides to automatically wire up
named controls with the properties of the same name (even being smart enough
to realize that the most "common" property of TextBox is the Text property).
While this approach is much more "wrist friendly", it suffers from the same
type of run-time failures: CM cannot know whether a binding should exist or
not.
ReactiveUI is presenting a new approach: wiring up controls via a declarative
syntax. This has a number of advantages:
* It's still wrist-friendly
* Bindings are clearly described in one place
* Bindings that are never valid (i.e. because the property name has changed)
break the build.
* This binding syntax isn't tied to Xaml - you can effectively use ReactiveUI
bindings with any UI framework with a bit of work, including Cocoa (MonoMac)
and GTK#.
Consider the following ViewModel, which is valid RxUI 3.x code as well:
public class MainPageViewModel : ReactiveObject
{
string _SomeText = "";
public string SomeText {
get { return _SomeText; }
set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
}
ObservableAsPropertyHelper<string> _FooMirror;
public string FooMirror {
get { return _FooMirror.Value; }
}
public ReactiveCommand Ok { get; protected set; }
public MainPageViewModel()
{
this.WhenAny(x => x.SomeText, x => x.Value)
.Select(x => "Foo" + x ?? "")
.ToProperty(this, x => x.FooMirror);
Ok = new ReactiveCommand();
}
}
In ReactiveUI 4.0, this is the way to wire up the View:
public partial class MainPage : Page, IViewFor<MainPageViewModel>
{
public MainPage()
{
ViewModel = new MainPageViewModel();
this.InitializeComponent();
// Connect the ViewModel's SomeText to the View's SomeText.Text
this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
// Since the View half isn't specified here, it will default to the
// control with the same name, and use the most "reasonable"
// property, just like Caliburn Micro
this.OneWayBind(ViewModel, x => x.FooMirror);
// Ditto with Commands, find a Control named "Ok"
this.BindCommand(ViewModel, x => x.Ok);
}
object IViewFor.ViewModel {
get { return ViewModel; }
set { ViewModel = (MainPageViewModel) value; }
}
public MainPageViewModel ViewModel { get; set; }
}
This feature is a work in progress, and there are definitely some cases that
need to be smoothed out. However, I'd love feedback on whether this is useful
or not.
I am unable to get the example to run because of this error:
The type 'System.Reactive.Concurrency.IScheduler' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Reactive.Interfaces, Version=2.0.20823.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
I am using Reactive Extensions 2.0 so I have a never version of System.Reactive.Interfaces. Using Win7 and VS2012RC. I am attempting to redirect the assembly to the never version via the app.config:
On Monday, August 27, 2012 2:01:11 AM UTC-7, Paul Betts wrote:
> ## ReactiveUI 4.0 Preview is live!
> After coding some pretty interesting new features, as well as to update to > the > latest released version of Rx (2.01), I am now releasing a preview release > of > ReactiveUI 4.0. You can get the binaries one of two ways:
> ### How does this break backwards compatibility?
> A few types have been renamed from 3.x (`IViewForViewModel` => > `IViewFor`), a > few deprecated methods have been removed (CollectionExtensions), and the > biggest one is that NLog is now optional - if you want to use it, make > sure to > install the `reactiveui-nlog` package (it comes by default in the > reactiveui > metapackage)
> ### WhenAny now works with any object!
> WhenAny and ObservableForProperty now work with *any* .NET object. The > runtime > will detect what kind of object it is (DependencyObject, INPC, etc) and > will > determine how to get notifications from it. Note that if you use WhenAny > with > an object that doesn't notify (like a regular .NET object), it will warn > you > on the logger that changes won't be reported. This framework is extensible > as > well, so on MonoMac for example, notifications for NSObjects will be > derived > using Key-Value Observing (KVO).
> This means that the old `ObservableForDP` method is now deprecated - use > WhenAny instead.
> ### View Bindings: A Compelling Replacement for XAML bindings
> There are currently two methods that are used in the XAML world for > binding > Views to ViewModels. The original method, XAML Bindings (i.e. {Binding > Foo}), > is quite flexible, but a frustrating aspect of it is that Bindings that > are > incorrect, due to typos or other mistakes, don't generate errors - you > only > see the error in the trace output. The Binding syntax can also get quite > verbose, and isn't always easy to verify because paths are relative to the > "nearest" DataContext set.
> Caliburn Micro decided to take a different approach, with their > "Convention-Based Wireup" - this approach decides to automatically wire up > named controls with the properties of the same name (even being smart > enough > to realize that the most "common" property of TextBox is the Text > property). > While this approach is much more "wrist friendly", it suffers from the > same > type of run-time failures: CM cannot know whether a binding should exist > or > not.
> ReactiveUI is presenting a new approach: wiring up controls via a > declarative > syntax. This has a number of advantages:
> * It's still wrist-friendly > * Bindings are clearly described in one place > * Bindings that are never valid (i.e. because the property name has > changed) > break the build. > * This binding syntax isn't tied to Xaml - you can effectively use > ReactiveUI > bindings with any UI framework with a bit of work, including Cocoa > (MonoMac) > and GTK#.
> Consider the following ViewModel, which is valid RxUI 3.x code as well:
> public class MainPageViewModel : ReactiveObject > { > string _SomeText = ""; > public string SomeText { > get { return _SomeText; } > set { this.RaiseAndSetIfChanged(x => x.SomeText, value); } > }
> ObservableAsPropertyHelper<string> _FooMirror; > public string FooMirror { > get { return _FooMirror.Value; } > }
> public ReactiveCommand Ok { get; protected set; }
> public MainPageViewModel() > { > this.WhenAny(x => x.SomeText, x => x.Value) > .Select(x => "Foo" + x ?? "") > .ToProperty(this, x => x.FooMirror);
> Ok = new ReactiveCommand(); > } > }
> In ReactiveUI 4.0, this is the way to wire up the View:
> public partial class MainPage : Page, IViewFor<MainPageViewModel> > { > public MainPage() > { > ViewModel = new MainPageViewModel(); > this.InitializeComponent();
> // Connect the ViewModel's SomeText to the View's SomeText.Text > this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
> // Since the View half isn't specified here, it will default to > the > // control with the same name, and use the most "reasonable" > // property, just like Caliburn Micro > this.OneWayBind(ViewModel, x => x.FooMirror);
> // Ditto with Commands, find a Control named "Ok" > this.BindCommand(ViewModel, x => x.Ok); > }
> object IViewFor.ViewModel { > get { return ViewModel; } > set { ViewModel = (MainPageViewModel) value; } > } > public MainPageViewModel ViewModel { get; set; } > }
> This feature is a work in progress, and there are definitely some cases > that > need to be smoothed out. However, I'd love feedback on whether this is > useful > or not.
> -- > Paul Betts <pa...@paulbetts.org <javascript:>>
You need to use RTM of VS2012. There is also a bug at the moment I
should've mentioned, you need to set the project to .NET 4.0, or else
you'll get the .NET 4.5 version of Rx when using NuGet, which is
supposedly backwards compatible, but you can see how backwards
compatible it is :)
On Mon, Aug 27, 2012 at 12:36 PM, Ducky Burke <anb...@gmail.com> wrote:
> Paul,
> I am unable to get the example to run because of this error:
> The type 'System.Reactive.Concurrency.IScheduler' is defined in an assembly
> that is not referenced. You must add a reference to assembly
> 'System.Reactive.Interfaces, Version=2.0.20823.0, Culture=neutral,
> PublicKeyToken=31bf3856ad364e35'.
> I am using Reactive Extensions 2.0 so I have a never version of
> System.Reactive.Interfaces. Using Win7 and VS2012RC. I am attempting to
> redirect the assembly to the never version via the app.config:
> But this still does not work. Is the source for ReactiveUI 4.0 Preview 2
> available yet?
> On Monday, August 27, 2012 2:01:11 AM UTC-7, Paul Betts wrote:
>> ## ReactiveUI 4.0 Preview is live!
>> After coding some pretty interesting new features, as well as to update to
>> the
>> latest released version of Rx (2.01), I am now releasing a preview release
>> of
>> ReactiveUI 4.0. You can get the binaries one of two ways:
>> ### How does this break backwards compatibility?
>> A few types have been renamed from 3.x (`IViewForViewModel` =>
>> `IViewFor`), a
>> few deprecated methods have been removed (CollectionExtensions), and the
>> biggest one is that NLog is now optional - if you want to use it, make
>> sure to
>> install the `reactiveui-nlog` package (it comes by default in the
>> reactiveui
>> metapackage)
>> ### WhenAny now works with any object!
>> WhenAny and ObservableForProperty now work with *any* .NET object. The
>> runtime
>> will detect what kind of object it is (DependencyObject, INPC, etc) and
>> will
>> determine how to get notifications from it. Note that if you use WhenAny
>> with
>> an object that doesn't notify (like a regular .NET object), it will warn
>> you
>> on the logger that changes won't be reported. This framework is extensible
>> as
>> well, so on MonoMac for example, notifications for NSObjects will be
>> derived
>> using Key-Value Observing (KVO).
>> This means that the old `ObservableForDP` method is now deprecated - use
>> WhenAny instead.
>> ### View Bindings: A Compelling Replacement for XAML bindings
>> There are currently two methods that are used in the XAML world for
>> binding
>> Views to ViewModels. The original method, XAML Bindings (i.e. {Binding
>> Foo}),
>> is quite flexible, but a frustrating aspect of it is that Bindings that
>> are
>> incorrect, due to typos or other mistakes, don't generate errors - you
>> only
>> see the error in the trace output. The Binding syntax can also get quite
>> verbose, and isn't always easy to verify because paths are relative to the
>> "nearest" DataContext set.
>> Caliburn Micro decided to take a different approach, with their
>> "Convention-Based Wireup" - this approach decides to automatically wire up
>> named controls with the properties of the same name (even being smart
>> enough
>> to realize that the most "common" property of TextBox is the Text
>> property).
>> While this approach is much more "wrist friendly", it suffers from the
>> same
>> type of run-time failures: CM cannot know whether a binding should exist
>> or
>> not.
>> ReactiveUI is presenting a new approach: wiring up controls via a
>> declarative
>> syntax. This has a number of advantages:
>> * It's still wrist-friendly
>> * Bindings are clearly described in one place
>> * Bindings that are never valid (i.e. because the property name has
>> changed)
>> break the build.
>> * This binding syntax isn't tied to Xaml - you can effectively use
>> ReactiveUI
>> bindings with any UI framework with a bit of work, including Cocoa
>> (MonoMac)
>> and GTK#.
>> Consider the following ViewModel, which is valid RxUI 3.x code as well:
>> public class MainPageViewModel : ReactiveObject
>> {
>> string _SomeText = "";
>> public string SomeText {
>> get { return _SomeText; }
>> set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
>> }
>> ObservableAsPropertyHelper<string> _FooMirror;
>> public string FooMirror {
>> get { return _FooMirror.Value; }
>> }
>> public ReactiveCommand Ok { get; protected set; }
>> public MainPageViewModel()
>> {
>> this.WhenAny(x => x.SomeText, x => x.Value)
>> .Select(x => "Foo" + x ?? "")
>> .ToProperty(this, x => x.FooMirror);
>> Ok = new ReactiveCommand();
>> }
>> }
>> In ReactiveUI 4.0, this is the way to wire up the View:
>> public partial class MainPage : Page, IViewFor<MainPageViewModel>
>> {
>> public MainPage()
>> {
>> ViewModel = new MainPageViewModel();
>> this.InitializeComponent();
>> // Connect the ViewModel's SomeText to the View's SomeText.Text
>> this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
>> // Since the View half isn't specified here, it will default to
>> the
>> // control with the same name, and use the most "reasonable"
>> // property, just like Caliburn Micro
>> this.OneWayBind(ViewModel, x => x.FooMirror);
>> // Ditto with Commands, find a Control named "Ok"
>> this.BindCommand(ViewModel, x => x.Ok);
>> }
>> object IViewFor.ViewModel {
>> get { return ViewModel; }
>> set { ViewModel = (MainPageViewModel) value; }
>> }
>> public MainPageViewModel ViewModel { get; set; }
>> }
>> This feature is a work in progress, and there are definitely some cases
>> that
>> need to be smoothed out. However, I'd love feedback on whether this is
>> useful
>> or not.
Thanks Paul. I don't have the RTM version because I don't have MSDN. I have
been using .NET 4.5 so that I can use EntityFramework 5.0. Since I am
starting a new project I have been attempting to use the latest version of
everything I can.
Once I get VS2012 RTM, will I be able to use ReactiveUI with .NET 4.5?
On Mon, Aug 27, 2012 at 12:56 PM, Paul Betts <paul.be...@gmail.com> wrote:
> Hi Ducky,
> You need to use RTM of VS2012. There is also a bug at the moment I
> should've mentioned, you need to set the project to .NET 4.0, or else
> you'll get the .NET 4.5 version of Rx when using NuGet, which is
> supposedly backwards compatible, but you can see how backwards
> compatible it is :)
> On Mon, Aug 27, 2012 at 12:36 PM, Ducky Burke <anb...@gmail.com> wrote:
> > Paul,
> > I am unable to get the example to run because of this error:
> > The type 'System.Reactive.Concurrency.IScheduler' is defined in an
> assembly
> > that is not referenced. You must add a reference to assembly
> > 'System.Reactive.Interfaces, Version=2.0.20823.0, Culture=neutral,
> > PublicKeyToken=31bf3856ad364e35'.
> > I am using Reactive Extensions 2.0 so I have a never version of
> > System.Reactive.Interfaces. Using Win7 and VS2012RC. I am attempting to
> > redirect the assembly to the never version via the app.config:
> > But this still does not work. Is the source for ReactiveUI 4.0 Preview 2
> > available yet?
> > On Monday, August 27, 2012 2:01:11 AM UTC-7, Paul Betts wrote:
> >> ## ReactiveUI 4.0 Preview is live!
> >> After coding some pretty interesting new features, as well as to update
> to
> >> the
> >> latest released version of Rx (2.01), I am now releasing a preview
> release
> >> of
> >> ReactiveUI 4.0. You can get the binaries one of two ways:
> >> ### How does this break backwards compatibility?
> >> A few types have been renamed from 3.x (`IViewForViewModel` =>
> >> `IViewFor`), a
> >> few deprecated methods have been removed (CollectionExtensions), and the
> >> biggest one is that NLog is now optional - if you want to use it, make
> >> sure to
> >> install the `reactiveui-nlog` package (it comes by default in the
> >> reactiveui
> >> metapackage)
> >> ### WhenAny now works with any object!
> >> WhenAny and ObservableForProperty now work with *any* .NET object. The
> >> runtime
> >> will detect what kind of object it is (DependencyObject, INPC, etc) and
> >> will
> >> determine how to get notifications from it. Note that if you use WhenAny
> >> with
> >> an object that doesn't notify (like a regular .NET object), it will warn
> >> you
> >> on the logger that changes won't be reported. This framework is
> extensible
> >> as
> >> well, so on MonoMac for example, notifications for NSObjects will be
> >> derived
> >> using Key-Value Observing (KVO).
> >> This means that the old `ObservableForDP` method is now deprecated - use
> >> WhenAny instead.
> >> ### View Bindings: A Compelling Replacement for XAML bindings
> >> There are currently two methods that are used in the XAML world for
> >> binding
> >> Views to ViewModels. The original method, XAML Bindings (i.e. {Binding
> >> Foo}),
> >> is quite flexible, but a frustrating aspect of it is that Bindings that
> >> are
> >> incorrect, due to typos or other mistakes, don't generate errors - you
> >> only
> >> see the error in the trace output. The Binding syntax can also get quite
> >> verbose, and isn't always easy to verify because paths are relative to
> the
> >> "nearest" DataContext set.
> >> Caliburn Micro decided to take a different approach, with their
> >> "Convention-Based Wireup" - this approach decides to automatically wire
> up
> >> named controls with the properties of the same name (even being smart
> >> enough
> >> to realize that the most "common" property of TextBox is the Text
> >> property).
> >> While this approach is much more "wrist friendly", it suffers from the
> >> same
> >> type of run-time failures: CM cannot know whether a binding should exist
> >> or
> >> not.
> >> ReactiveUI is presenting a new approach: wiring up controls via a
> >> declarative
> >> syntax. This has a number of advantages:
> >> * It's still wrist-friendly
> >> * Bindings are clearly described in one place
> >> * Bindings that are never valid (i.e. because the property name has
> >> changed)
> >> break the build.
> >> * This binding syntax isn't tied to Xaml - you can effectively use
> >> ReactiveUI
> >> bindings with any UI framework with a bit of work, including Cocoa
> >> (MonoMac)
> >> and GTK#.
> >> Consider the following ViewModel, which is valid RxUI 3.x code as well:
> >> public class MainPageViewModel : ReactiveObject
> >> {
> >> string _SomeText = "";
> >> public string SomeText {
> >> get { return _SomeText; }
> >> set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
> >> }
> >> ObservableAsPropertyHelper<string> _FooMirror;
> >> public string FooMirror {
> >> get { return _FooMirror.Value; }
> >> }
> >> public ReactiveCommand Ok { get; protected set; }
> >> public MainPageViewModel()
> >> {
> >> this.WhenAny(x => x.SomeText, x => x.Value)
> >> .Select(x => "Foo" + x ?? "")
> >> .ToProperty(this, x => x.FooMirror);
> >> Ok = new ReactiveCommand();
> >> }
> >> }
> >> In ReactiveUI 4.0, this is the way to wire up the View:
> >> public partial class MainPage : Page, IViewFor<MainPageViewModel>
> >> {
> >> public MainPage()
> >> {
> >> ViewModel = new MainPageViewModel();
> >> this.InitializeComponent();
> >> // Connect the ViewModel's SomeText to the View's
> SomeText.Text
> >> this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
> >> // Since the View half isn't specified here, it will default
> to
> >> the
> >> // control with the same name, and use the most "reasonable"
> >> // property, just like Caliburn Micro
> >> this.OneWayBind(ViewModel, x => x.FooMirror);
> >> // Ditto with Commands, find a Control named "Ok"
> >> this.BindCommand(ViewModel, x => x.Ok);
> >> }
> >> This feature is a work in progress, and there are definitely some cases
> >> that
> >> need to be smoothed out. However, I'd love feedback on whether this is
> >> useful
> >> or not.
Not at the moment, I need to make an entirely new set of binaries for
.NET 4.5. However, I will definitely add it for the next preview of
ReactiveUI 4.0 (I found about this glitch right as I was about to
release).
You can most likely make this work at the moment though if you:
1. Go into your project, and delete all references to System.Reactive.*
2. Add them back from your "packages" folder, but make *sure* to
choose the net40 versions
While the net45 versions have some useful debugging features, they are
mostly equivalent in terms of APIs.
On Mon, Aug 27, 2012 at 1:02 PM, Ducky Burke <anb...@gmail.com> wrote:
> Thanks Paul. I don't have the RTM version because I don't have MSDN. I have
> been using .NET 4.5 so that I can use EntityFramework 5.0. Since I am
> starting a new project I have been attempting to use the latest version of
> everything I can.
> Once I get VS2012 RTM, will I be able to use ReactiveUI with .NET 4.5?
> Thanks again for always answering.
> Alexandra
> On Mon, Aug 27, 2012 at 12:56 PM, Paul Betts <paul.be...@gmail.com> wrote:
>> Hi Ducky,
>> You need to use RTM of VS2012. There is also a bug at the moment I
>> should've mentioned, you need to set the project to .NET 4.0, or else
>> you'll get the .NET 4.5 version of Rx when using NuGet, which is
>> supposedly backwards compatible, but you can see how backwards
>> compatible it is :)
>> On Mon, Aug 27, 2012 at 12:36 PM, Ducky Burke <anb...@gmail.com> wrote:
>> > Paul,
>> > I am unable to get the example to run because of this error:
>> > The type 'System.Reactive.Concurrency.IScheduler' is defined in an
>> > assembly
>> > that is not referenced. You must add a reference to assembly
>> > 'System.Reactive.Interfaces, Version=2.0.20823.0, Culture=neutral,
>> > PublicKeyToken=31bf3856ad364e35'.
>> > I am using Reactive Extensions 2.0 so I have a never version of
>> > System.Reactive.Interfaces. Using Win7 and VS2012RC. I am attempting to
>> > redirect the assembly to the never version via the app.config:
>> > But this still does not work. Is the source for ReactiveUI 4.0 Preview 2
>> > available yet?
>> > On Monday, August 27, 2012 2:01:11 AM UTC-7, Paul Betts wrote:
>> >> ## ReactiveUI 4.0 Preview is live!
>> >> After coding some pretty interesting new features, as well as to update
>> >> to
>> >> the
>> >> latest released version of Rx (2.01), I am now releasing a preview
>> >> release
>> >> of
>> >> ReactiveUI 4.0. You can get the binaries one of two ways:
>> >> ### How does this break backwards compatibility?
>> >> A few types have been renamed from 3.x (`IViewForViewModel` =>
>> >> `IViewFor`), a
>> >> few deprecated methods have been removed (CollectionExtensions), and
>> >> the
>> >> biggest one is that NLog is now optional - if you want to use it, make
>> >> sure to
>> >> install the `reactiveui-nlog` package (it comes by default in the
>> >> reactiveui
>> >> metapackage)
>> >> ### WhenAny now works with any object!
>> >> WhenAny and ObservableForProperty now work with *any* .NET object. The
>> >> runtime
>> >> will detect what kind of object it is (DependencyObject, INPC, etc) and
>> >> will
>> >> determine how to get notifications from it. Note that if you use
>> >> WhenAny
>> >> with
>> >> an object that doesn't notify (like a regular .NET object), it will
>> >> warn
>> >> you
>> >> on the logger that changes won't be reported. This framework is
>> >> extensible
>> >> as
>> >> well, so on MonoMac for example, notifications for NSObjects will be
>> >> derived
>> >> using Key-Value Observing (KVO).
>> >> This means that the old `ObservableForDP` method is now deprecated -
>> >> use
>> >> WhenAny instead.
>> >> ### View Bindings: A Compelling Replacement for XAML bindings
>> >> There are currently two methods that are used in the XAML world for
>> >> binding
>> >> Views to ViewModels. The original method, XAML Bindings (i.e. {Binding
>> >> Foo}),
>> >> is quite flexible, but a frustrating aspect of it is that Bindings that
>> >> are
>> >> incorrect, due to typos or other mistakes, don't generate errors - you
>> >> only
>> >> see the error in the trace output. The Binding syntax can also get
>> >> quite
>> >> verbose, and isn't always easy to verify because paths are relative to
>> >> the
>> >> "nearest" DataContext set.
>> >> Caliburn Micro decided to take a different approach, with their
>> >> "Convention-Based Wireup" - this approach decides to automatically wire
>> >> up
>> >> named controls with the properties of the same name (even being smart
>> >> enough
>> >> to realize that the most "common" property of TextBox is the Text
>> >> property).
>> >> While this approach is much more "wrist friendly", it suffers from the
>> >> same
>> >> type of run-time failures: CM cannot know whether a binding should
>> >> exist
>> >> or
>> >> not.
>> >> ReactiveUI is presenting a new approach: wiring up controls via a
>> >> declarative
>> >> syntax. This has a number of advantages:
>> >> * It's still wrist-friendly
>> >> * Bindings are clearly described in one place
>> >> * Bindings that are never valid (i.e. because the property name has
>> >> changed)
>> >> break the build.
>> >> * This binding syntax isn't tied to Xaml - you can effectively use
>> >> ReactiveUI
>> >> bindings with any UI framework with a bit of work, including Cocoa
>> >> (MonoMac)
>> >> and GTK#.
>> >> Consider the following ViewModel, which is valid RxUI 3.x code as well:
>> >> public class MainPageViewModel : ReactiveObject
>> >> {
>> >> string _SomeText = "";
>> >> public string SomeText {
>> >> get { return _SomeText; }
>> >> set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
>> >> }
>> >> ObservableAsPropertyHelper<string> _FooMirror;
>> >> public string FooMirror {
>> >> get { return _FooMirror.Value; }
>> >> }
>> >> public ReactiveCommand Ok { get; protected set; }
>> >> public MainPageViewModel()
>> >> {
>> >> this.WhenAny(x => x.SomeText, x => x.Value)
>> >> .Select(x => "Foo" + x ?? "")
>> >> .ToProperty(this, x => x.FooMirror);
>> >> Ok = new ReactiveCommand();
>> >> }
>> >> }
>> >> In ReactiveUI 4.0, this is the way to wire up the View:
>> >> public partial class MainPage : Page, IViewFor<MainPageViewModel>
>> >> {
>> >> public MainPage()
>> >> {
>> >> ViewModel = new MainPageViewModel();
>> >> this.InitializeComponent();
>> >> // Connect the ViewModel's SomeText to the View's
>> >> SomeText.Text
>> >> this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
>> >> // Since the View half isn't specified here, it will default
>> >> to
>> >> the
>> >> // control with the same name, and use the most "reasonable"
>> >> // property, just like Caliburn Micro
>> >> this.OneWayBind(ViewModel, x => x.FooMirror);
>> >> // Ditto with Commands, find a Control named "Ok"
>> >> this.BindCommand(ViewModel, x => x.Ok);
>> >> }
>> >> This feature is a work in progress, and there are definitely some cases
>> >> that
>> >> need to be smoothed out. However, I'd love feedback on whether this is
>> >> useful
>> >> or not.
I did try what you said but that didn't work. Into some other errors,
including one that references the directory
Y:\Dropbox\ReactiveUI_External\ReactiveUI\Reflection.cs (in case that means
anything to you as that is not what my Y drive is mapped to).
I will wait until I get VS2012 RTM and then wait for the new binaries for
.NET 4.5.
On Mon, Aug 27, 2012 at 1:12 PM, Paul Betts <paul.be...@gmail.com> wrote:
> Not at the moment, I need to make an entirely new set of binaries for
> .NET 4.5. However, I will definitely add it for the next preview of
> ReactiveUI 4.0 (I found about this glitch right as I was about to
> release).
> You can most likely make this work at the moment though if you:
> 1. Go into your project, and delete all references to System.Reactive.*
> 2. Add them back from your "packages" folder, but make *sure* to
> choose the net40 versions
> While the net45 versions have some useful debugging features, they are
> mostly equivalent in terms of APIs.
> On Mon, Aug 27, 2012 at 1:02 PM, Ducky Burke <anb...@gmail.com> wrote:
> > Thanks Paul. I don't have the RTM version because I don't have MSDN. I
> have
> > been using .NET 4.5 so that I can use EntityFramework 5.0. Since I am
> > starting a new project I have been attempting to use the latest version
> of
> > everything I can.
> > Once I get VS2012 RTM, will I be able to use ReactiveUI with .NET 4.5?
> > Thanks again for always answering.
> > Alexandra
> > On Mon, Aug 27, 2012 at 12:56 PM, Paul Betts <paul.be...@gmail.com>
> wrote:
> >> Hi Ducky,
> >> You need to use RTM of VS2012. There is also a bug at the moment I
> >> should've mentioned, you need to set the project to .NET 4.0, or else
> >> you'll get the .NET 4.5 version of Rx when using NuGet, which is
> >> supposedly backwards compatible, but you can see how backwards
> >> compatible it is :)
> >> On Mon, Aug 27, 2012 at 12:36 PM, Ducky Burke <anb...@gmail.com> wrote:
> >> > Paul,
> >> > I am unable to get the example to run because of this error:
> >> > The type 'System.Reactive.Concurrency.IScheduler' is defined in an
> >> > assembly
> >> > that is not referenced. You must add a reference to assembly
> >> > 'System.Reactive.Interfaces, Version=2.0.20823.0, Culture=neutral,
> >> > PublicKeyToken=31bf3856ad364e35'.
> >> > I am using Reactive Extensions 2.0 so I have a never version of
> >> > System.Reactive.Interfaces. Using Win7 and VS2012RC. I am attempting
> to
> >> > redirect the assembly to the never version via the app.config:
> >> > But this still does not work. Is the source for ReactiveUI 4.0
> Preview 2
> >> > available yet?
> >> > On Monday, August 27, 2012 2:01:11 AM UTC-7, Paul Betts wrote:
> >> >> ## ReactiveUI 4.0 Preview is live!
> >> >> After coding some pretty interesting new features, as well as to
> update
> >> >> to
> >> >> the
> >> >> latest released version of Rx (2.01), I am now releasing a preview
> >> >> release
> >> >> of
> >> >> ReactiveUI 4.0. You can get the binaries one of two ways:
> >> >> * `install-package reactiveui -pre` or `install-package
> >> >> reactiveui-winrt
> >> >> -pre`
> >> >> * Download the Zip release [from
> >> >> GitHub](https://github.com/xpaulbettsx/ReactiveUI/downloads)
> >> >> ### How does this break backwards compatibility?
> >> >> A few types have been renamed from 3.x (`IViewForViewModel` =>
> >> >> `IViewFor`), a
> >> >> few deprecated methods have been removed (CollectionExtensions), and
> >> >> the
> >> >> biggest one is that NLog is now optional - if you want to use it,
> make
> >> >> sure to
> >> >> install the `reactiveui-nlog` package (it comes by default in the
> >> >> reactiveui
> >> >> metapackage)
> >> >> ### WhenAny now works with any object!
> >> >> WhenAny and ObservableForProperty now work with *any* .NET object.
> The
> >> >> runtime
> >> >> will detect what kind of object it is (DependencyObject, INPC, etc)
> and
> >> >> will
> >> >> determine how to get notifications from it. Note that if you use
> >> >> WhenAny
> >> >> with
> >> >> an object that doesn't notify (like a regular .NET object), it will
> >> >> warn
> >> >> you
> >> >> on the logger that changes won't be reported. This framework is
> >> >> extensible
> >> >> as
> >> >> well, so on MonoMac for example, notifications for NSObjects will be
> >> >> derived
> >> >> using Key-Value Observing (KVO).
> >> >> This means that the old `ObservableForDP` method is now deprecated -
> >> >> use
> >> >> WhenAny instead.
> >> >> ### View Bindings: A Compelling Replacement for XAML bindings
> >> >> There are currently two methods that are used in the XAML world for
> >> >> binding
> >> >> Views to ViewModels. The original method, XAML Bindings (i.e.
> {Binding
> >> >> Foo}),
> >> >> is quite flexible, but a frustrating aspect of it is that Bindings
> that
> >> >> are
> >> >> incorrect, due to typos or other mistakes, don't generate errors -
> you
> >> >> only
> >> >> see the error in the trace output. The Binding syntax can also get
> >> >> quite
> >> >> verbose, and isn't always easy to verify because paths are relative
> to
> >> >> the
> >> >> "nearest" DataContext set.
> >> >> Caliburn Micro decided to take a different approach, with their
> >> >> "Convention-Based Wireup" - this approach decides to automatically
> wire
> >> >> up
> >> >> named controls with the properties of the same name (even being smart
> >> >> enough
> >> >> to realize that the most "common" property of TextBox is the Text
> >> >> property).
> >> >> While this approach is much more "wrist friendly", it suffers from
> the
> >> >> same
> >> >> type of run-time failures: CM cannot know whether a binding should
> >> >> exist
> >> >> or
> >> >> not.
> >> >> ReactiveUI is presenting a new approach: wiring up controls via a
> >> >> declarative
> >> >> syntax. This has a number of advantages:
> >> >> * It's still wrist-friendly
> >> >> * Bindings are clearly described in one place
> >> >> * Bindings that are never valid (i.e. because the property name has
> >> >> changed)
> >> >> break the build.
> >> >> * This binding syntax isn't tied to Xaml - you can effectively use
> >> >> ReactiveUI
> >> >> bindings with any UI framework with a bit of work, including Cocoa
> >> >> (MonoMac)
> >> >> and GTK#.
> >> >> Consider the following ViewModel, which is valid RxUI 3.x code as
> well:
> >> >> public class MainPageViewModel : ReactiveObject
> >> >> {
> >> >> string _SomeText = "";
> >> >> public string SomeText {
> >> >> get { return _SomeText; }
> >> >> set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
> >> >> }
> >> >> public ReactiveCommand Ok { get; protected set; }
> >> >> public MainPageViewModel()
> >> >> {
> >> >> this.WhenAny(x => x.SomeText, x => x.Value)
> >> >> .Select(x => "Foo" + x ?? "")
> >> >> .ToProperty(this, x => x.FooMirror);
> >> >> Ok = new ReactiveCommand();
> >> >> }
> >> >> }
> >> >> In ReactiveUI 4.0, this is the way to wire up the View:
> >> >> public partial class MainPage : Page, IViewFor<MainPageViewModel>
> >> >> {
> >> >> public MainPage()
> >> >> {
> >> >> ViewModel = new MainPageViewModel();
> >> >> this.InitializeComponent();
> >> >> // Connect the ViewModel's SomeText to the View's
> >> >> SomeText.Text
> >> >> this.Bind(ViewModel, x => x.SomeText, x =>
> x.SomeText.Text);
> >> >> // Since the View half isn't specified here, it will
> default
> >> >> to
> >> >> the
> >> >> // control with the same name, and use the most
> "reasonable"
> >> >> // property, just like Caliburn Micro
> >> >> this.OneWayBind(ViewModel, x => x.FooMirror);
> >> >> // Ditto with Commands, find a Control named "Ok"
> >> >> this.BindCommand(ViewModel, x => x.Ok);
> >> >> }
> >> >> This feature is a work in progress, and there are definitely some
> cases
> >> >> that
> >> >> need to be smoothed out. However, I'd love feedback on whether this
> is
> >> >> useful
> >> >> or not.
> >> >> --
> >> >> Paul Betts <pa...@paulbetts.org>
> ### View Bindings: A Compelling Replacement for XAML bindings
> [...]
> public class MainPageViewModel : ReactiveObject
> {
> string _SomeText = "";
> public string SomeText {
> get { return _SomeText; }
> set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
> }
> ObservableAsPropertyHelper<string> _FooMirror;
> public string FooMirror {
> get { return _FooMirror.Value; }
> }
> public ReactiveCommand Ok { get; protected set; }
> public MainPageViewModel()
> {
> this.WhenAny(x => x.SomeText, x => x.Value)
> .Select(x => "Foo" + x ?? "")
> .ToProperty(this, x => x.FooMirror);
> Ok = new ReactiveCommand();
> }
> }
> In ReactiveUI 4.0, this is the way to wire up the View:
> public partial class MainPage : Page, IViewFor<MainPageViewModel>
> {
> public MainPage()
> {
> ViewModel = new MainPageViewModel();
> this.InitializeComponent();
> // Connect the ViewModel's SomeText to the View's SomeText.Text
> this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
> // Since the View half isn't specified here, it will default to the
> // control with the same name, and use the most "reasonable"
> // property, just like Caliburn Micro
> this.OneWayBind(ViewModel, x => x.FooMirror);
> // Ditto with Commands, find a Control named "Ok"
> this.BindCommand(ViewModel, x => x.Ok);
> }
> object IViewFor.ViewModel {
> get { return ViewModel; }
> set { ViewModel = (MainPageViewModel) value; }
> }
> public MainPageViewModel ViewModel { get; set; }
> }
> This feature is a work in progress, and there are definitely some cases that
> need to be smoothed out. However, I'd love feedback on whether this is useful
> or not.
How should I handle changes to the "ViewModel" property itself with
this binding syntax? In my case "ViewModel" gets assigned after the
view is constructed, and can possibly change during the lifetime of
the view (I'm using "ViewModelViewHost" to automatically create views
for view models provided by the main view model). I came up with the
following (after "InitializeComponent()" in "MainPage()"):
var bindings = new CompositeDisposable();
this.WhenAny(s => s.ViewModel, c => c.Value).Subscribe(vm =>
{
// Clear old bindings
bindings.Dispose();
if (vm != null)
{
bindings.Add(this.Bind(vm, x => x.SomeText, x => x.SomeText.Text));
bindings.Add(this.OneWayBind(vm, x => x.FooMirror));
bindings.Add(this.BindCommand(vm, x => x.Ok));
}
else
{
this.SomeText.Text = null;
this.FooMirror.Text = null;
this.Ok.Command = null;
}
});
Works (if "ViewModel" is a DP, of course), but feels clumsy, mostly
because I need to reset the bound properties manually if the view
model gets removed by assigning "null" to the "ViewModel" property.
WPF data binding handles this transparently, and automatically assigns
"null" if any property in the binding chain becomes "null".
ReactiveUI handles this scenario for you actually, as long as ViewModel is
a DependencyProperty, with Bind as well as with WhenAny, as long as you
write your WhenAny against 'this' (i.e. this.WhenAny(x => x.ViewModel.Foo)
vs ViewModel.WhenAny(...))
So, moral of the story is, as long as everything is "this.(Method)", it
will do what you want.
On Aug 28, 2012 5:31 AM, "Sebastian Wiesner" <lunary...@gmail.com> wrote:
> 2012/8/27 Paul Betts <paul.be...@gmail.com>:
> > ### View Bindings: A Compelling Replacement for XAML bindings
> > [...]
> > public class MainPageViewModel : ReactiveObject
> > {
> > string _SomeText = "";
> > public string SomeText {
> > get { return _SomeText; }
> > set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
> > }
> > ObservableAsPropertyHelper<string> _FooMirror;
> > public string FooMirror {
> > get { return _FooMirror.Value; }
> > }
> > public ReactiveCommand Ok { get; protected set; }
> > public MainPageViewModel()
> > {
> > this.WhenAny(x => x.SomeText, x => x.Value)
> > .Select(x => "Foo" + x ?? "")
> > .ToProperty(this, x => x.FooMirror);
> > Ok = new ReactiveCommand();
> > }
> > }
> > In ReactiveUI 4.0, this is the way to wire up the View:
> > public partial class MainPage : Page, IViewFor<MainPageViewModel>
> > {
> > public MainPage()
> > {
> > ViewModel = new MainPageViewModel();
> > this.InitializeComponent();
> > // Connect the ViewModel's SomeText to the View's SomeText.Text
> > this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
> > // Since the View half isn't specified here, it will default
> to the
> > // control with the same name, and use the most "reasonable"
> > // property, just like Caliburn Micro
> > this.OneWayBind(ViewModel, x => x.FooMirror);
> > // Ditto with Commands, find a Control named "Ok"
> > this.BindCommand(ViewModel, x => x.Ok);
> > }
> > This feature is a work in progress, and there are definitely some cases
> that
> > need to be smoothed out. However, I'd love feedback on whether this is
> useful
> > or not.
> How should I handle changes to the "ViewModel" property itself with
> this binding syntax? In my case "ViewModel" gets assigned after the
> view is constructed, and can possibly change during the lifetime of
> the view (I'm using "ViewModelViewHost" to automatically create views
> for view models provided by the main view model). I came up with the
> following (after "InitializeComponent()" in "MainPage()"):
> var bindings = new CompositeDisposable();
> this.WhenAny(s => s.ViewModel, c => c.Value).Subscribe(vm =>
> {
> // Clear old bindings
> bindings.Dispose();
> if (vm != null)
> {
> bindings.Add(this.Bind(vm, x => x.SomeText, x => x.SomeText.Text));
> bindings.Add(this.OneWayBind(vm, x => x.FooMirror));
> bindings.Add(this.BindCommand(vm, x => x.Ok));
> }
> else
> {
> this.SomeText.Text = null;
> this.FooMirror.Text = null;
> this.Ok.Command = null;
> }
> });
> Works (if "ViewModel" is a DP, of course), but feels clumsy, mostly
> because I need to reset the bound properties manually if the view
> model gets removed by assigning "null" to the "ViewModel" property.
> WPF data binding handles this transparently, and automatically assigns
> "null" if any property in the binding chain becomes "null".
> ReactiveUI handles this scenario for you actually, as long as ViewModel is a
> DependencyProperty, with Bind as well as with WhenAny, as long as you write
> your WhenAny against 'this' (i.e. this.WhenAny(x => x.ViewModel.Foo) vs
> ViewModel.WhenAny(...))
> So, moral of the story is, as long as everything is "this.(Method)", it will
> do what you want.
Do I understand correctly that "this.Bind(this.ViewModel, x => x.Foo)"
will also handle changes of "this.ViewModel" properly?
> On Aug 28, 2012 5:31 AM, "Sebastian Wiesner" <lunary...@gmail.com> wrote:
>> 2012/8/27 Paul Betts <paul.be...@gmail.com>:
>> > ### View Bindings: A Compelling Replacement for XAML bindings
>> > [...]
>> > public class MainPageViewModel : ReactiveObject
>> > {
>> > string _SomeText = "";
>> > public string SomeText {
>> > get { return _SomeText; }
>> > set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
>> > }
>> > ObservableAsPropertyHelper<string> _FooMirror;
>> > public string FooMirror {
>> > get { return _FooMirror.Value; }
>> > }
>> > public ReactiveCommand Ok { get; protected set; }
>> > public MainPageViewModel()
>> > {
>> > this.WhenAny(x => x.SomeText, x => x.Value)
>> > .Select(x => "Foo" + x ?? "")
>> > .ToProperty(this, x => x.FooMirror);
>> > Ok = new ReactiveCommand();
>> > }
>> > }
>> > In ReactiveUI 4.0, this is the way to wire up the View:
>> > public partial class MainPage : Page, IViewFor<MainPageViewModel>
>> > {
>> > public MainPage()
>> > {
>> > ViewModel = new MainPageViewModel();
>> > this.InitializeComponent();
>> > // Connect the ViewModel's SomeText to the View's
>> > SomeText.Text
>> > this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
>> > // Since the View half isn't specified here, it will default
>> > to the
>> > // control with the same name, and use the most "reasonable"
>> > // property, just like Caliburn Micro
>> > this.OneWayBind(ViewModel, x => x.FooMirror);
>> > // Ditto with Commands, find a Control named "Ok"
>> > this.BindCommand(ViewModel, x => x.Ok);
>> > }
>> > This feature is a work in progress, and there are definitely some cases
>> > that
>> > need to be smoothed out. However, I'd love feedback on whether this is
>> > useful
>> > or not.
>> How should I handle changes to the "ViewModel" property itself with
>> this binding syntax? In my case "ViewModel" gets assigned after the
>> view is constructed, and can possibly change during the lifetime of
>> the view (I'm using "ViewModelViewHost" to automatically create views
>> for view models provided by the main view model). I came up with the
>> following (after "InitializeComponent()" in "MainPage()"):
>> var bindings = new CompositeDisposable();
>> this.WhenAny(s => s.ViewModel, c => c.Value).Subscribe(vm =>
>> {
>> // Clear old bindings
>> bindings.Dispose();
>> if (vm != null)
>> {
>> bindings.Add(this.Bind(vm, x => x.SomeText, x =>
>> x.SomeText.Text));
>> bindings.Add(this.OneWayBind(vm, x => x.FooMirror));
>> bindings.Add(this.BindCommand(vm, x => x.Ok));
>> }
>> else
>> {
>> this.SomeText.Text = null;
>> this.FooMirror.Text = null;
>> this.Ok.Command = null;
>> }
>> });
>> Works (if "ViewModel" is a DP, of course), but feels clumsy, mostly
>> because I need to reset the bound properties manually if the view
>> model gets removed by assigning "null" to the "ViewModel" property.
>> WPF data binding handles this transparently, and automatically assigns
>> "null" if any property in the binding chain becomes "null".
> 2012/8/28 Paul Betts <paul.be...@gmail.com>:
> > ReactiveUI handles this scenario for you actually, as long as ViewModel
> is a
> > DependencyProperty, with Bind as well as with WhenAny, as long as you
> write
> > your WhenAny against 'this' (i.e. this.WhenAny(x => x.ViewModel.Foo) vs
> > ViewModel.WhenAny(...))
> > So, moral of the story is, as long as everything is "this.(Method)", it
> will
> > do what you want.
> Do I understand correctly that "this.Bind(this.ViewModel, x => x.Foo)"
> will also handle changes of "this.ViewModel" properly?
> > On Aug 28, 2012 5:31 AM, "Sebastian Wiesner" <lunary...@gmail.com>
> wrote:
> >> 2012/8/27 Paul Betts <paul.be...@gmail.com>:
> >> > ### View Bindings: A Compelling Replacement for XAML bindings
> >> > [...]
> >> > public class MainPageViewModel : ReactiveObject
> >> > {
> >> > string _SomeText = "";
> >> > public string SomeText {
> >> > get { return _SomeText; }
> >> > set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
> >> > }
> >> > public ReactiveCommand Ok { get; protected set; }
> >> > public MainPageViewModel()
> >> > {
> >> > this.WhenAny(x => x.SomeText, x => x.Value)
> >> > .Select(x => "Foo" + x ?? "")
> >> > .ToProperty(this, x => x.FooMirror);
> >> > Ok = new ReactiveCommand();
> >> > }
> >> > }
> >> > In ReactiveUI 4.0, this is the way to wire up the View:
> >> > public partial class MainPage : Page, IViewFor<MainPageViewModel>
> >> > {
> >> > public MainPage()
> >> > {
> >> > ViewModel = new MainPageViewModel();
> >> > this.InitializeComponent();
> >> > // Connect the ViewModel's SomeText to the View's
> >> > SomeText.Text
> >> > this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
> >> > // Since the View half isn't specified here, it will default
> >> > to the
> >> > // control with the same name, and use the most "reasonable"
> >> > // property, just like Caliburn Micro
> >> > this.OneWayBind(ViewModel, x => x.FooMirror);
> >> > // Ditto with Commands, find a Control named "Ok"
> >> > this.BindCommand(ViewModel, x => x.Ok);
> >> > }
> >> > This feature is a work in progress, and there are definitely some
> cases
> >> > that
> >> > need to be smoothed out. However, I'd love feedback on whether this is
> >> > useful
> >> > or not.
> >> How should I handle changes to the "ViewModel" property itself with
> >> this binding syntax? In my case "ViewModel" gets assigned after the
> >> view is constructed, and can possibly change during the lifetime of
> >> the view (I'm using "ViewModelViewHost" to automatically create views
> >> for view models provided by the main view model). I came up with the
> >> following (after "InitializeComponent()" in "MainPage()"):
> >> var bindings = new CompositeDisposable();
> >> this.WhenAny(s => s.ViewModel, c => c.Value).Subscribe(vm =>
> >> {
> >> // Clear old bindings
> >> bindings.Dispose();
> >> if (vm != null)
> >> {
> >> bindings.Add(this.Bind(vm, x => x.SomeText, x =>
> >> x.SomeText.Text));
> >> bindings.Add(this.OneWayBind(vm, x => x.FooMirror));
> >> bindings.Add(this.BindCommand(vm, x => x.Ok));
> >> }
> >> else
> >> {
> >> this.SomeText.Text = null;
> >> this.FooMirror.Text = null;
> >> this.Ok.Command = null;
> >> }
> >> });
> >> Works (if "ViewModel" is a DP, of course), but feels clumsy, mostly
> >> because I need to reset the bound properties manually if the view
> >> model gets removed by assigning "null" to the "ViewModel" property.
> >> WPF data binding handles this transparently, and automatically assigns
> >> "null" if any property in the binding chain becomes "null".
> On Aug 28, 2012 10:01 AM, "Sebastian Wiesner" <lunary...@gmail.com> wrote:
>> 2012/8/28 Paul Betts <paul.be...@gmail.com>:
>> > ReactiveUI handles this scenario for you actually, as long as ViewModel
>> > is a
>> > DependencyProperty, with Bind as well as with WhenAny, as long as you
>> > write
>> > your WhenAny against 'this' (i.e. this.WhenAny(x => x.ViewModel.Foo) vs
>> > ViewModel.WhenAny(...))
>> > So, moral of the story is, as long as everything is "this.(Method)", it
>> > will
>> > do what you want.
>> Do I understand correctly that "this.Bind(this.ViewModel, x => x.Foo)"
>> will also handle changes of "this.ViewModel" properly?
>> > On Aug 28, 2012 5:31 AM, "Sebastian Wiesner" <lunary...@gmail.com>
>> > wrote:
>> >> 2012/8/27 Paul Betts <paul.be...@gmail.com>:
>> >> > ### View Bindings: A Compelling Replacement for XAML bindings
>> >> > [...]
>> >> > public class MainPageViewModel : ReactiveObject
>> >> > {
>> >> > string _SomeText = "";
>> >> > public string SomeText {
>> >> > get { return _SomeText; }
>> >> > set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
>> >> > }
>> >> > public ReactiveCommand Ok { get; protected set; }
>> >> > public MainPageViewModel()
>> >> > {
>> >> > this.WhenAny(x => x.SomeText, x => x.Value)
>> >> > .Select(x => "Foo" + x ?? "")
>> >> > .ToProperty(this, x => x.FooMirror);
>> >> > Ok = new ReactiveCommand();
>> >> > }
>> >> > }
>> >> > In ReactiveUI 4.0, this is the way to wire up the View:
>> >> > public partial class MainPage : Page, IViewFor<MainPageViewModel>
>> >> > {
>> >> > public MainPage()
>> >> > {
>> >> > ViewModel = new MainPageViewModel();
>> >> > this.InitializeComponent();
>> >> > // Connect the ViewModel's SomeText to the View's
>> >> > SomeText.Text
>> >> > this.Bind(ViewModel, x => x.SomeText, x =>
>> >> > x.SomeText.Text);
>> >> > // Since the View half isn't specified here, it will
>> >> > default
>> >> > to the
>> >> > // control with the same name, and use the most
>> >> > "reasonable"
>> >> > // property, just like Caliburn Micro
>> >> > this.OneWayBind(ViewModel, x => x.FooMirror);
>> >> > // Ditto with Commands, find a Control named "Ok"
>> >> > this.BindCommand(ViewModel, x => x.Ok);
>> >> > }
>> >> > This feature is a work in progress, and there are definitely some
>> >> > cases
>> >> > that
>> >> > need to be smoothed out. However, I'd love feedback on whether this
>> >> > is
>> >> > useful
>> >> > or not.
>> >> How should I handle changes to the "ViewModel" property itself with
>> >> this binding syntax? In my case "ViewModel" gets assigned after the
>> >> view is constructed, and can possibly change during the lifetime of
>> >> the view (I'm using "ViewModelViewHost" to automatically create views
>> >> for view models provided by the main view model). I came up with the
>> >> following (after "InitializeComponent()" in "MainPage()"):
>> >> var bindings = new CompositeDisposable();
>> >> this.WhenAny(s => s.ViewModel, c => c.Value).Subscribe(vm =>
>> >> {
>> >> // Clear old bindings
>> >> bindings.Dispose();
>> >> if (vm != null)
>> >> {
>> >> bindings.Add(this.Bind(vm, x => x.SomeText, x =>
>> >> x.SomeText.Text));
>> >> bindings.Add(this.OneWayBind(vm, x => x.FooMirror));
>> >> bindings.Add(this.BindCommand(vm, x => x.Ok));
>> >> }
>> >> else
>> >> {
>> >> this.SomeText.Text = null;
>> >> this.FooMirror.Text = null;
>> >> this.Ok.Command = null;
>> >> }
>> >> });
>> >> Works (if "ViewModel" is a DP, of course), but feels clumsy, mostly
>> >> because I need to reset the bound properties manually if the view
>> >> model gets removed by assigning "null" to the "ViewModel" property.
>> >> WPF data binding handles this transparently, and automatically assigns
>> >> "null" if any property in the binding chain becomes "null".
I’ve just started trying out RxUI 4 - I really like the binding syntax.
I’m trying to use it with the MahApps.Metro library in VS2010 with .Net 4.0.
Everything’s going fine so far, except for binding to WindowCommands.
This is clearly a problem with other auto-binding frameworks too, since
they have a workaround in their docs for Caliburn.Micro. The docs say this:
Caliburn.Micro <http://caliburnmicro.codeplex.com/> automatically binds on
the visual tree and a couple of other locations, which doesn’t cover how
MahApps.Metro’s awesome WindowCommands are implemented. To work around this
issue for a simple button to action binding, first add the cal namespace to
the root element (usually Controls:MetroWindow):
At the moment I’m working around it by using a XAML binding to bind the
button’s Command property to a ReactiveCommand in the ViewModel, but I was
wondering if there was anything akin to Caliburn’s Message.Attach in RxUI
so I can use BindCommand here as well.
Thanks in advance
John Stovin
*From:* Paul Betts <paul.be...@gmail.com>
*Sent:* 27 August 2012 10:01
*To:* ReactiveUI mailing list <reactivexaml@googlegroups.com>
*Subject:* Announcing ReactiveUI 4.0 Preview 2
## ReactiveUI 4.0 Preview is live!
After coding some pretty interesting new features, as well as to update to
the
latest released version of Rx (2.01), I am now releasing a preview release
of
ReactiveUI 4.0. You can get the binaries one of two ways:
A few types have been renamed from 3.x (`IViewForViewModel` => `IViewFor`),
a
few deprecated methods have been removed (CollectionExtensions), and the
biggest one is that NLog is now optional - if you want to use it, make sure
to
install the `reactiveui-nlog` package (it comes by default in the reactiveui
metapackage)
### WhenAny now works with any object!
WhenAny and ObservableForProperty now work with *any* .NET object. The
runtime
will detect what kind of object it is (DependencyObject, INPC, etc) and will
determine how to get notifications from it. Note that if you use WhenAny
with
an object that doesn't notify (like a regular .NET object), it will warn you
on the logger that changes won't be reported. This framework is extensible
as
well, so on MonoMac for example, notifications for NSObjects will be derived
using Key-Value Observing (KVO).
This means that the old `ObservableForDP` method is now deprecated - use
WhenAny instead.
### View Bindings: A Compelling Replacement for XAML bindings
There are currently two methods that are used in the XAML world for binding
Views to ViewModels. The original method, XAML Bindings (i.e. {Binding
Foo}),
is quite flexible, but a frustrating aspect of it is that Bindings that are
incorrect, due to typos or other mistakes, don't generate errors - you only
see the error in the trace output. The Binding syntax can also get quite
verbose, and isn't always easy to verify because paths are relative to the
"nearest" DataContext set.
Caliburn Micro decided to take a different approach, with their
"Convention-Based Wireup" - this approach decides to automatically wire up
named controls with the properties of the same name (even being smart enough
to realize that the most "common" property of TextBox is the Text property).
While this approach is much more "wrist friendly", it suffers from the same
type of run-time failures: CM cannot know whether a binding should exist or
not.
ReactiveUI is presenting a new approach: wiring up controls via a
declarative
syntax. This has a number of advantages:
* It's still wrist-friendly
* Bindings are clearly described in one place
* Bindings that are never valid (i.e. because the property name has changed)
break the build.
* This binding syntax isn't tied to Xaml - you can effectively use
ReactiveUI
bindings with any UI framework with a bit of work, including Cocoa
(MonoMac)
and GTK#.
Consider the following ViewModel, which is valid RxUI 3.x code as well:
public class MainPageViewModel : ReactiveObject
{
string _SomeText = "";
public string SomeText {
get { return _SomeText; }
set { this.RaiseAndSetIfChanged(x => x.SomeText, value); }
}
ObservableAsPropertyHelper<string> _FooMirror;
public string FooMirror {
get { return _FooMirror.Value; }
}
public ReactiveCommand Ok { get; protected set; }
public MainPageViewModel()
{
this.WhenAny(x => x.SomeText, x => x.Value)
.Select(x => "Foo" + x ?? "")
.ToProperty(this, x => x.FooMirror);
Ok = new ReactiveCommand();
}
}
In ReactiveUI 4.0, this is the way to wire up the View:
public partial class MainPage : Page, IViewFor<MainPageViewModel>
{
public MainPage()
{
ViewModel = new MainPageViewModel();
this.InitializeComponent();
// Connect the ViewModel's SomeText to the View's SomeText.Text
this.Bind(ViewModel, x => x.SomeText, x => x.SomeText.Text);
// Since the View half isn't specified here, it will default to
the
// control with the same name, and use the most "reasonable"
// property, just like Caliburn Micro
this.OneWayBind(ViewModel, x => x.FooMirror);
// Ditto with Commands, find a Control named "Ok"
this.BindCommand(ViewModel, x => x.Ok);
}
object IViewFor.ViewModel {
get { return ViewModel; }
set { ViewModel = (MainPageViewModel) value; }
}
public MainPageViewModel ViewModel { get; set; }
}
This feature is a work in progress, and there are definitely some cases that
need to be smoothed out. However, I'd love feedback on whether this is
useful
or not.
congratulations on the release - love your work :)
Just an observation for discussion from my side : doesn't specifying the bindings in the setup of the ViewModel like this make Unit Testing very difficult? How would you go about creating unit tests for the ViewModel in your example, for instance?
So, the bindings that are new to RxUI 4.0 are *View* Bindings. i.e. binding
ViewModel.FirstName to TextBox.Text, replacing {Binding} in the XAML. You're
setting these up in the code-behind of the View (your UserControl or Window).
You're right that these are untestable, but the idea of MVVM is that we want
to move all of the interesting behavior code to the ViewModel, and make the
View be as uninteresting as possible, *because* you can't test the View.
Since the ViewModel is just a regular object, we can create it in a test, poke
at its properties, invoke ICommands, etc etc. And hopefully, the code we put
into the view will be so straightforward and boring that there won't be any
mistakes (since for many cases, it will just be a bunch of Bind and OneWayBind
calls).
On Thu, Aug 30, 2012 at 03:47:31AM -0700, Ryan Britton wrote:
> Hi Paul,
> congratulations on the release - love your work :)
> Just an observation for discussion from my side : doesn't specifying the > bindings in the setup of the ViewModel like this make Unit Testing very > difficult? How would you go about creating unit tests for the ViewModel in > your example, for instance?
Hmmm, so there are two ways to fix this (not knowing much about MahApps's
Magic here):
The first is, BindCommand lets you specify an arbitrary event to bind to, so
if you can name the button you're binding to, you can bind it to the Clicked
event.
The 2nd way is a bit more work, but is more elegant - you can actually teach
ReactiveUI how to bind ICommands to arbitrary controls, by implementing the
ICreatesCommandBinding interface, and calling the new RxApp.Register to
register it with the service locator.
On Wed, Aug 29, 2012 at 09:54:11PM +0000, John Stovin wrote:
> Hi Paul,
> I’ve just started trying out RxUI 4 - I really like the binding syntax.
> I’m trying to use it with the MahApps.Metro library in VS2010 with .Net 4.0.
> Everything’s going fine so far, except for binding to WindowCommands.
> This is clearly a problem with other auto-binding frameworks too, since
> they have a workaround in their docs for Caliburn.Micro. The docs say this:
> Caliburn.Micro <http://caliburnmicro.codeplex.com/> automatically binds on
> the visual tree and a couple of other locations, which doesn’t cover how
> MahApps.Metro’s awesome WindowCommands are implemented. To work around this
> issue for a simple button to action binding, first add the cal namespace to
> the root element (usually Controls:MetroWindow):
> At the moment I’m working around it by using a XAML binding to bind the
> button’s Command property to a ReactiveCommand in the ViewModel, but I was
> wondering if there was anything akin to Caliburn’s Message.Attach in RxUI
> so I can use BindCommand here as well.
> Hmmm, so there are two ways to fix this (not knowing much about MahApps's
> Magic here):
> The first is, BindCommand lets you specify an arbitrary event to bind to,
> so
> if you can name the button you're binding to, you can bind it to the
> Clicked
> event.
> The 2nd way is a bit more work, but is more elegant - you can actually
> teach
> ReactiveUI how to bind ICommands to arbitrary controls, by implementing the
> ICreatesCommandBinding interface, and calling the new RxApp.Register to
> register it with the service locator.
> On Wed, Aug 29, 2012 at 09:54:11PM +0000, John Stovin wrote:
> > Hi Paul,
> > I’ve just started trying out RxUI 4 - I really like the binding syntax.
> > I’m trying to use it with the MahApps.Metro library in VS2010 with .Net
> 4.0.
> > Everything’s going fine so far, except for binding to WindowCommands.
> > This is clearly a problem with other auto-binding frameworks too, since
> > they have a workaround in their docs for Caliburn.Micro. The docs say
> this:
> > Caliburn.Micro <http://caliburnmicro.codeplex.com/> automatically binds
> on
> > the visual tree and a couple of other locations, which doesn’t cover how
> > MahApps.Metro’s awesome WindowCommands are implemented. To work around
> this
> > issue for a simple button to action binding, first add the cal namespace
> to
> > the root element (usually Controls:MetroWindow):
> > At the moment I’m working around it by using a XAML binding to bind the
> > button’s Command property to a ReactiveCommand in the ViewModel, but I
> was
> > wondering if there was anything akin to Caliburn’s Message.Attach in RxUI
> > so I can use BindCommand here as well.