Binding Code and Data to MCML
Data binding is the way in which you bind code and data to MCML. ModelItem objects are code-supported objects that represent the most common abstract data and callback concepts and are strictly non-visual. These objects should be used as the main interface to the UI controls that are defined in your MCML markup.
The ModelItem class implements the IPropertyObject interface, and provides the following features:
- Change notifications.
- Direct simple bindings, which allow you to associate a property on your ModelItem object with a property on another object, or vice versa. For the ModelItem object to detect property changes on a different object, the other object must implement the IPropertyObject interface.
For convenience, you can use the following ModelItem methods for binding to other code objects:
- BindFromSource, which creates a binding between a remote source object and a ModelItem object.
- BindToTarget, which creates a one-way binding from a ModelItem object to a target.
- TwoWayBind, which creates a two-way binding between a ModelItem object and a target.
- Lifetime management. ModelItem objects are typically connected to many other objects through event handlers and other methods. To prevent common leaks, each ModelItem must be owned by an IModelItemOwner object. That owner then takes responsibility for disposing the owned ModelItem objects.
The ModelItem class implements the IModelItemOwner interface; one ModelItem can own others, thereby ensuring that ModelItem objects that are being referenced by another ModelItem object are automatically disposed and released. For example, a page ModelItem object could own all of the ModelItem objects on the page.
Windows Media Center supports binding data from any .NET object, as well as generalized data sources through a set of data interfaces. If the source exposes IPropertyObject notifications, MCML rules can automatically respond.
Note Your code cannot access UI elements—UI elements own the data binding relationship, rather than the code owning it.
You can derive custom classes from the ModelItem class and reference them from your MCML. The Microsoft.MediaCenter.UI namespace provides the ModelItem class and the following derived classes that you can use directly:
| Type | Description |
| Choice | Maintains a list and the item within it that is selected. This class is useful when you want to implement a radio button group. |
| BooleanChoice | Maintains a list of two options (True and False) and the item that is selected. This class is useful when you want to implement a check box. |
| Command InvokeCommand (MCML) NavigateCommand (MCML) | Provides callback functionality so you can connect the UI to the program state. For example, use one of these classes with a UI button to receive click notifications. |
| EditableText | Represents an editable string. This class is useful when you want to implement an edit box. |
| ListDataSet ArrayListDataSet | Maintains a list of objects for a list or a gallery in the UI. These classes raise events for add, remove, and modified notifications, which are compatible with Repeater view items. |
| RangedValue ByteRangedValue IntRangedValue | Maintains a range of values. For example, use these classes to implement a spinner control or a slider control. |
| Timer | Creates a configurable timer that raises notifications on clock ticks (that is, specific intervals). |
| PropertySet | Provides a loosely-typed dictionary that raises notifications. However, when possible, use a strongly-typed structure instead. This class works well where data structures are required, but custom code is not possible (such as Web applications). |
The following example shows a simple way of binding code to data:
Samples.Fundamentals.cs
This class creates a contact record using hard-coded data.
using System;
namespace Samples.Fundamentals
{
public class SimpleContact
{
public string Name
{
get
{
return "John Doe";
}
}
public string Email
{
get
{
return "johndoe@hotmail.com";
}
}
}
}
This MCML file references the assembly created from the code above:
<Mcml xmlns="http://schemas.microsoft.com/2006/mcml"
xmlns:fn="assembly://McmlSampler/Samples.Fundamentals" >
<UI Name="CodeDataBinding">
<Locals>
<!-- Create an instance of the simple contact. -->
<fn:SimpleContact Name="Contact"/>
</Locals>
<Content>
<!-- Display a background image. -->
<Graphic Content="file://CircuitBoard.png" Padding="2,2,8,8" MinimumSize="159,126">
<Layout>
<FlowLayout Orientation="Vertical" ItemAlignment="Center"/>
</Layout>
<Children>
<!-- SimpleContact contains two String properties: Name and Email. -->
<!-- Bind to the properties on the contact. -->
<Text Content="[Contact.Name]" Font="Tahoma,25" Color="Navy"/>
<Text Content="[Contact.Email]" Font="Tahoma,10" Color="Black"/>
</Children>
</Graphic>
</Content>
</UI>
</Mcml>
The following example shows a custom clock that is derived from ModelItem. This object sends a notification on every time change using a timer that is set to an interval of one second.
using System;
using Microsoft.MediaCenter.UI;
namespace Samples.CodeData.ModelItems
{
// Clock class derived from ModelItem.
public class Clock : ModelItem
{
public Clock()
{
// Set up a timer to refresh the clock.
// The clock is the owner of the timer, so when the clock is disposed,
// the objects it owns are also disposed of automatically.
_timer = new Timer(this);
_timer.Interval = 1000;
_timer.Tick += delegate { RefreshTime(); };
_timer.Enabled = true;
RefreshTime();
}
// Current time.
public string Time
{
get
{
return _time;
}
set
{
if (_time != value)
{
_time = value;
FirePropertyChanged("Time");
}
}
}
// Update the time.
private void RefreshTime()
{
Time = DateTime.Now.ToString();
}
private string _time = String.Empty;
private Timer _timer;
}
}
The MCML markup creates an instance of a Clock class defined above. Using Rules, whenever the clock ticks, a text label is updated with the time and a sound file is played.
<Mcml
xmlns="http://schemas.microsoft.com/2006/mcml"
xmlns:c="assembly://McmlSampler/Samples.CodeData.ModelItems">
<UI Name="ModelItems">
<Locals>
<!-- Create an instance of the Clock class. -->
<c:Clock Name="Clock"/>
</Locals>
<Rules>
<!-- Bind the clock's time value to a Text view item. -->
<Binding Source="[Clock.Time]" Target="[Label.Content]">
<Actions>
<PlaySound Sound="file://Tick.wav"/>
</Actions>
</Binding>
</Rules>
<Content>
<Text Name="Label" Color="PowderBlue" Font="Verdana,40"/>
</Content>
</UI>
</Mcml>
See Also