Perspex controls expose their properties as standard CLR properties, so for reading and writing values there's no surprises:
// Create a TextBlock and set its Text property.
var textBlock = new TextBlock();
textBlock.Text = "Hello World!";
However there's a lot more you can do with properties such as subscribing to changes on the property, and binding.
You can subscribe to changes on a property by calling the GetObservable
method. This returns an IObservable<T>
which can be used to listen for changes
to the property:
var textBlock = new TextBlock();
var text = textBlock.GetObservable(TextBlock.TextProperty);
Each property that can be subscribed to has a static readonly field called
[PropertyName]Property
which is passed to GetObservable
in order to
subscribe to the property's changes.
IObservable
(part of Reactive Extensions, or rx for short) is out of scope
for this guide, but here's an example which uses the returned observable to
print a message with the changing property values to the console:
var textBlock = new TextBlock();
var text = textBlock.GetObservable(TextBlock.TextProperty);
text.Subscribe(value => Console.WriteLine(value + " Changed"));
When the returned observable is subscribed, it will return the current value
of the property immediately and then push a new value each time the property
changes. If you don't want the current value, you can use the rx Skip
operator:
var text = textBlock.GetObservable(TextBlock.TextProperty).Skip(1);
Observables don't just go one way! You can also use them to bind properties.
For example here we create two TextBlock
s and bind the second's Text
property to the first:
var textBlock1 = new TextBlock();
var textBlock2 = new TextBlock();
// Get an observable for the first text block's Text property.
var source = textBlock1.GetObservable(TextBlock.TextProperty);
// And bind it to the second.
textBlock2.Bind(TextBlock.TextProperty, source);
// Changes to the first TextBlock's Text property will now be propagated
// to the second.
textBlock1.Text = "Goodbye Cruel World";
// Prints "Goodbye Cruel World"
Console.WriteLine(textBlock2.Text);
The GetObservable
method returns an observable that tracks changes to a
property on a single instance. However, if you're writing a control you may
want to implement an OnPropertyChanged
method. In WPF this is done by passing
a static PropertyChangedCallback
to the DependencyProperty
registration
method, but in Perspex it's slightly different (and hopefully easier!)
The field which defines the property is derived from PerspexProperty
and this
has a Changed
observable which is fired every time the property changes on
any object. In addition there is an AddClassHandler
extension method which
can automatically route the event to a method on your control.
For example if you want to listen to changes to your control's Foo
property
you'd do it like this:
static MyControl()
{
FooProperty.Changed.AddClassHandler<MyControl>(x => x.FooChanged);
}
private void FooChanged(PerspexPropertyChangedEventArgs e)
{
// The 'e' parameter describes what's changed.
}