Skip to content

Commit 67e41cd

Browse files
committed
Merge branch 'user-documentation'
2 parents a475965 + a33b74f commit 67e41cd

File tree

2 files changed

+255
-0
lines changed

2 files changed

+255
-0
lines changed

docs/migrating-from-rxui4.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
## How to migrate from ReactiveUI 4.x
2+
3+
Moving to ReactiveUI 5.0 is usually straightforward, but there are a few things
4+
to know.
5+
6+
### Changes that may be more difficult to deal with
7+
8+
* ReactiveUI 5.0 is .NET 4.5 only - this means that Silverlight 5, .NET 4.0, and
9+
WP7.x are all unsupported. If you want to use ReactiveUI with these platforms,
10+
you have to stay on the 4.x series. You can do this by changing the lines in
11+
your "packages.config" to always use the latest version from the 4.x series:
12+
13+
```xml
14+
<package id="reactiveui-core" version="(4.0.0, 5.0.0)" />
15+
```
16+
17+
* ReactiveCommand now does not have an imperative constructor (i.e.
18+
`ReactiveCommand.Create`). This constructor is something that
19+
you probably shouldn't be using anyways, but if you really need it, you can
20+
find the original ReactiveCommand in the `ReactiveUI.Legacy` namespace.
21+
22+
* ReactiveUI now uses a much more simplified Service Location (i.e. IoC without
23+
injection) model than RxUI 4.x. However, this new interface
24+
(`IMutableDependencyResolver`) is not always straightforward to implement with
25+
existing IoC containers. The method `RxApp.InitializeCustomResolver` as well
26+
as the `FuncDependencyResolver` can be used during IoC setup to help you out.
27+
If you never used a custom IoC container, then you don't have to do anything
28+
here, It Just Works™.
29+
30+
* Validation has been removed, this will be re-added in a future release. If you
31+
need this, grab the old version of the class [from
32+
here](https://github.com/reactiveui/ReactiveUI/blob/4.6.4/ReactiveUI/Validation.cs)
33+
34+
### Changes that are pretty easy to deal with
35+
36+
* `ReactiveCollection` is now `ReactiveList`
37+
38+
* Many things that were in `ReactiveUI.Xaml` are now in `ReactiveUI`
39+
40+
* The `ReactiveUI.Routing` namespace is gone, it has been moved into
41+
`ReactiveUI` and `ReactiveUI.{Cocoa/Xaml/Android}` - in general, the
42+
"Platform" DLLs are now much smaller and only contain platform-specific
43+
controls.
44+
45+
* ReactiveAsyncCommand and ReactiveCommand are now the same class, and some of
46+
the async registration methods have changed.
47+
48+
* The old syntax for declaring read-write properties is now removed, the *only*
49+
correct way to declare properties is now:
50+
51+
```cs
52+
int foo;
53+
public int Foo {
54+
get { return foo; }
55+
set { this.RaiseAndSetIfChanged(ref foo, value); }
56+
}
57+
```
58+
59+
* ToProperty no longer sets the ObservableAsPropertyHelper variable via
60+
reflection - instead, it is set via an `out` property.
61+
62+
* `RxApp.DeferredScheduler` is now called `RxApp.MainThreadScheduler`
63+
64+
* Many old "for compatibility only" methods have now been removed - there is no
65+
functionality loss

docs/overview.md

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# ReactiveUI
2+
3+
ReactiveUI is a compelling combination of MVVM and Reactive Extensions (Rx).
4+
Combining these two make managing concurrency as well as expressing complicated
5+
interactions between objects possible in a declarative, functional way. Put
6+
simply, if you’ve ever had to chain events / callbacks together and declare
7+
state ints/booleans to keep track of what’s going on, Reactive Extensions
8+
provides a sane alternative.
9+
10+
## What’s in this library
11+
- **ReactiveObject** - a ViewModel object based on Josh Smith’s implementation,
12+
that also implements IObservable as a way to notify property changes. It also
13+
allows a straightforward way to observe the changes of a single property.
14+
- **ReactiveCommand** - an implementation of ICommand that is also a Subject
15+
whose OnNext is raised when Execute is executed. Its CanExecute can also be
16+
defined by an IObservable which means the UI will instantly update instead of
17+
implementations which rely on RequerySuggested in WPF. ReactiveCommand
18+
encapsulates the common pattern of “Fire asynchronous command, then marshal
19+
result back onto dispatcher thread”. It also allows you to control if
20+
concurrency is allowed.
21+
- **ObservableAsPropertyHelper<T>** - a class that easily lets you convert an
22+
IObservable into a property that stores its latest value, as well as fires
23+
NotifyPropertyChanged when the property changes. This is really useful for
24+
combining existing properties together and replacing IValueConverters, since
25+
your ViewModels will also be IObservables.
26+
- **ReactiveList<T>** - a custom implementation of an ObservableCollection which
27+
allows you to see changes in the collection as observables.
28+
- **MessageBus** - a reactive implementation of the Publish/Subscribe pattern,
29+
usefull to decouple your objects, while still being able to communicate.
30+
- **MemoizingMRUCache** - a cache that only remembers a specified number of
31+
recently used items.
32+
- **ObservableAsyncMRUCache** - a thread-safe, asynchronous MemoizingMRUCache.
33+
- **ReactiveBinding** - a powerful and flexible cross-platform binding framework
34+
as an alternative for Xaml bindings.
35+
36+
## Organization
37+
38+
This library is organized into several high-level assemblies:
39+
40+
- **ReactiveUI** - Core library that doesn't rely on any particular UI
41+
framework. `ReactiveObject`, the base ViewModel object, as well as
42+
`ReactiveList<T>`, a more awesome ObservableCollection, `ReactiveCommand`, an
43+
implementation of ICommand, and the Binding framework are in here.
44+
45+
- **ReactiveUI.Platforms** - Classes that require references to a Xaml'ly
46+
framework, like WPF or WinRT. This assembly also contains the Xaml part of the
47+
Binding framework and a screens and navigation framework usefull for
48+
navigating back and forward between views based on ViewModels.
49+
50+
- **ReactiveUI.Blend** - This class has several Blend Behaviors and Triggers
51+
that make attaching ViewModel changes to Visual State Manager states.
52+
53+
- **ReactiveUI.Mobile** - Useful classes when developing for a mobile platforms
54+
such as Windows Phone or the Windows Runtime. These classes handle things
55+
like persisting state and reacting to application lifetime events.
56+
57+
## ReactiveObject
58+
59+
Like any other MVVM framework, ReactiveUI has an object designed as a ViewModel
60+
class. This object is based on Josh Smith’s ObservableObject implementation in
61+
MVVM Foundation (actually, many of the classes’ inspiration come from MVVM
62+
Foundation, Josh does awesome work!). The Reactive version as you can imagine,
63+
implements INotifyPropertyChanged as well as IObservable so that you can
64+
subscribe to object property changes.
65+
66+
ReactiveObject also does a few nice things for you: first, when you compile
67+
ReactiveUI in Debug mode, it will print debug messages using its logging
68+
framework whenever a property changes. Another example is, implementing the
69+
standard pattern of a property that raises the changed event is a few lines
70+
shorter and makes effective use of the new CallerMemberName attribute:
71+
72+
```cs
73+
int _someProp;
74+
public int SomeProp {
75+
get { return _someProp; }
76+
set { this.RaiseAndSetIfChanged(ref _someProp, value); }
77+
}
78+
```
79+
80+
## ReactiveCommand
81+
82+
ReactiveCommand is an ICommand implementation that is simultaneously a
83+
RelayCommand implementation, as well as some extra bits that are pretty
84+
motivating. We can provide an IObservable as our CanExecute. For example, here’s
85+
a command that can only run when the mouse is up:
86+
87+
```cs
88+
var mouseIsUp = Observable.Merge(
89+
Observable.FromEvent<MouseButtonEventArgs>(window, ”MouseDown”).Select(_ => false),
90+
Observable.FromEvent<MouseButtonEventArgs>(window, ”MouseUp”).Select(_ => true),
91+
).StartWith(true);
92+
93+
var cmd = new ReactiveCommand(mouseIsUp);
94+
cmd.Subscribe(x => Console.WriteLine(x));
95+
```
96+
97+
Or, how about a command that can only run if two other commands are disabled:
98+
99+
```cs
100+
// Pretend these were already initialized to something more interesting
101+
var cmd1 = new ReactiveCommand();
102+
var cmd2 = new ReactiveCommand();
103+
104+
var can_exec = cmd1.CanExecuteObservable.CombineLatest(cmd2.CanExecuteObservable, (lhs, rhs) => !(lhs && rhs));
105+
var new_cmd = new ReactiveCommand(can_exec);
106+
new_cmd.Subscribe(Console.WriteLine);
107+
```
108+
109+
One thing that’s important to notice here, is that the command’s CanExecute
110+
updates immediately, instead of relying on CommandManager.RequerySuggested. If
111+
you’ve ever had the problem in WPF or Silverlight where your buttons don’t
112+
reenable themselves until you switch focus or click them, you’ve seen this bug.
113+
Using an IObservable means that the Commanding framework knows exactly when the
114+
state changes, and doesn’t need to requery every command object on the page.
115+
116+
### What about Execute?
117+
118+
This is where ReactiveCommand’s IObservable implementation comes in.
119+
ReactiveCommand itself can be observed, and it provides new items whenever
120+
Execute is called (the items being the parameter passed into the Execute call).
121+
This means, that Subscribe can act the same as the Execute Action, or we can
122+
actually get a fair bit more clever. For example:
123+
124+
```cs
125+
var cmd = new ReactiveCommand();
126+
cmd.Where(x => ((int)x) % 2 == 0).Subscribe(x => Console.WriteLine(”Even numbers like {0} are cool!”, x));
127+
cmd.Where(x => ((int)x) % 2 != 0).Timestamps().Subscribe(x => Console.WriteLine(”Odd numbers like {0} are even cooler, especially at {1}!”, x.Value, x.Timestamp));
128+
129+
cmd.Execute(2);
130+
>>>Even numbers like 2 are cool!
131+
132+
cmd.Execute(5);
133+
>>>Odd numbers like 5 are even cooler, especially at (the current time)!
134+
```
135+
136+
### Running commands async.
137+
If you’ve done any C#/Xaml programming that does any sort of interesting work,
138+
you know that one of the difficult things is that if you do things in an event
139+
handler that take a lot of time, like reading a large file or downloading
140+
something over a network, you will quickly find that you have a problem: you
141+
either block the UI, or when you can’t even do blocking operations at all,
142+
you’ll just run it on another thread. Then, you find the 2nd tricky part that WPF
143+
and Silverlight objects have thread affinity. Meaning, that you can only access
144+
objects from the thread that created them. So, at the end of the computation
145+
when you go to runtextBox.Text = results;, you suddenly get an Exception.
146+
Dispatcher.BeginInvoke solves this So, once you dig around on the Internet a
147+
bit, you find out the pattern to solve this problem involves the Dispatcher:
148+
149+
```cs
150+
void SomeUIEvent(object o, EventArgs e) {
151+
var some_data = this.SomePropertyICanOnlyGetOnTheUIThread;
152+
var t = new Task(() => {
153+
var result = doSomethingInTheBackground(some_data);
154+
Dispatcher.BeginInvoke(new Action(() => { this.UIPropertyThatWantsTheCalculation = result; }));
155+
}
156+
157+
t.Start();
158+
}
159+
```
160+
161+
We use this pattern a lot, so when we run a command, we often are just:
162+
1. The command executes, we kick off a thread
163+
2. We calculate something that takes a long time
164+
3. We take the result, and set a property on the UI thread, using Dispatcher
165+
166+
ReactiveCommand encapsulates this pattern by allowing you to register a Task or
167+
IObservable to execute. It also gives you other thing for free. For example, you
168+
often only want one async instance running, and the Command should be disabled
169+
while we are still processing. Another common thing you would want to do is,
170+
display some sort of UI while an async action is running - something like a
171+
spinner control or a progress bar being displayed.
172+
173+
Here’s a simple use of a Command, who will run a task in the background, and
174+
only allow one at a time (i.e. its CanExecute will return false until the action
175+
completes)
176+
177+
```cs
178+
var cmd = new ReactiveCommand(null, false, /* do not allow concurrent requests */ null);
179+
cmd.RegisterAsyncAction(i => {
180+
Thread.Sleep((int)i * 1000); // Pretend to do work
181+
};
182+
183+
cmd.Execute(5 /*seconds*/);
184+
cmd.CanExecute(5); // False! We’re still chewing on the first one.
185+
```
186+
187+
## Learn more
188+
189+
For more information on how to use ReactiveUI, check out
190+
[ReactiveUI](http://www.reactiveui.net).

0 commit comments

Comments
 (0)