-
-
Notifications
You must be signed in to change notification settings - Fork 10
first binding
To connect the component declared in IML
to your code in c#
, attribute values of IML accept binding expressions enclosed in {}
.
First, create a public property in your main application class:
class MyApplication : Interface {
public string Message { get; set; }
static void Main (string[] args) {
using (MyApplication app = new MyApplication ())
app.Run ();
Next, in your IML, this property may be accessed enclosed in {}
:
<Label Text="{Message}"/>
This simple expression will try to find the requested member in the current DataSource
. Usually, the top level datasource of IML is set on loading:
protected override void OnInitialized () {
base.OnInitialized ();//the base method just raises the Initilized event.
Load ("test.crow").DataSource = this;
}
DataSource
once set at one level, is accessible to all the descendants, except if you set the RootDataLevel
property of the widget to true
.
This is ok for constant value, but what if you want to track value changes. In crow, classes that will act as data provider should implement the IValueChange
interface.
The Interface
class already implement it, so you may notify changes by calling:
NotifyValueChanged ("Message", "this is the new message content");
This notification is usualy donne in the property setter:
public string Message {
get => message;
set {
message = value;
NotifyValueChanged ("Message", message);
}
}
You may also notify changes to the IML component without actually creating the property. This is called property less bindings
.
As soon as a binding is expressed in IML, the binding system will listen to changes with that name.
If the class that you want to use as binding provider has not implemented the IValueChange
interface, the initial value of the target member will be load on startup but no change will be noticed.
The typical implementation for value change is has follow, the only requirement is the ValueChange event
, but it's common to add helper method to ease notifications:
public abstract class CommandBase : IValueChange {
public event EventHandler<ValueChangeEventArgs> ValueChanged;
public virtual void NotifyValueChanged(string MemberName, object _value) {
ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
}
You may also use the CallerMemberName
attribute of the System.Runtime.CompilerServices
so that the member name in the notify call will be set automatically by the compiler:
public void NotifyValueChanged (object _value, [CallerMemberName] string caller = null) {
NotifyValueChanged (caller, _value);
}
Then when you are in a property and wand to notify its change, you may call the notify method with only the value argument, but only if the member name is the same as the property your're in
public bool Status {
get => status;
set {
status = value;
NotifyValueChanged (status);
}
}
crow implement two ways to set default and recurent values.
Each time you define a new crow property, you may decorate it with the [Default] attribute.
[DefaultValue (true)]
public bool Status {
get => status;
set {
status = value;
NotifyValueChanged ("status");
}
}
All the embedded files in assemblies ending with the .style
extension will be loaded for styling. There you may declare global properties per widget type, or use special style
name that you will set in the Style
property of your control:
for example, to define that all the labels must have their width set to Fit
:
Label {
Width="Fit";
}
And if you want a bunch of labels that will have their background of a special color without setting it everywhere in IML, you may declare a special style:
MyCustomLabel {
Background="Jet";
}
And then in your IML
, use the Style
property:
<Label Style="MyCustomLabel" Text="{Message}"/>
Styles and themes may be used to change ui apparence very simply. See Styling page for more informations.