As I mentioned before, I will be working on a series of posts on new features in Silverlight 30. This post is all about ElementName binding.
Probably my favorite feature in Silverlight 3 that affects developers writing business applications is addition of ElementName property to Binding object. This features existed in WPF since version 1, but was missing from Silverlight 2.0. The basic strategy behind the feature is the ability to bind a property on one UI element to a property on another UI element. Here is a very common scenario in a business application that this features makes much simpler to implement. Say, you have two co-dependent combo boxes. For example, you have a combo box with a listing of states, and once a state is selected, second combo box is populated with a list of cities for that state.
The basic syntax for ElementName binding is as follows:
ItemsSource="{Binding ElementName=ParentCombo, Path=…
In my case, I am going to illustrate the feature by having a list of dozens, each with a list of numbers that belong to that dozen. Here are my classes:
public class Each
{
public string Name { get; set; }
public int Id { get; set; }
public static Each GetEach(int id)
{
Each newEach = new Each();
newEach.Id = id;
newEach.Name = id.ToString();
return newEach;
}
}
public class Eaches : List<Each>
{
}
public class Dozen
{
public string Name { get; set; }
public int Id { get; set; }
public Eaches Items {get;set;}
public static Dozen GetDozen(int id)
{
Dozen newDozen = new Dozen();
newDozen.Id = id;
newDozen.Name = id.ToString();
newDozen.Items = new Eaches();
for (int i = 1; i <= 12; i++)
{
newDozen.Items.Add(Each.GetEach(((id – 1) * 12) + i));
}
return newDozen;
}
}
public class Dozens : List<Dozen>
{
public Dozens()
{
for (int i = 1; i < 10; i++)
{
Add(Dozen.GetDozen(i));
}
}
}
Now, I am going to add my Dozens class as a resource to a xaml page:
<UserControl x:Class="SilverlightApplication7.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SilverlightApplication7"
mc:Ignorable="d"
d:DesignWidth="640"
d:DesignHeight="480"
>
<UserControl.Resources>
<local:Dozens x:Key="data"/>
</UserControl.Resources>
The last step is to tie two combo boxes together:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ComboBox x:Name="ParentCombo" Width="300" HorizontalAlignment="Left" ItemsSource="{StaticResource data}" DisplayMemberPath="Name"/>
<ComboBox x:Name="ChildCombo" Grid.Row="2" Width="300" HorizontalAlignment="Left" ItemsSource="{Binding ElementName=ParentCombo, Path=SelectedItem.Items}" DisplayMemberPath="Name"/>
</Grid>
Here is the summary of what we did. We used Dozens class (the list of Dozen objects) that was populated when its constructor was invoked as part of resources collection initialization. Then we used this object to populate ParentCombo with data. We set DisplayMemberPath to show a desired property in combo box. Then we used SelectedItem property from ParentCombo to be the source of items in ChildCombo. As the user selects an item in ParentCombo, we can see that list of items inside ChildCombo is changing without any code-behind. We also use dotted syntax (Path=SelectedItem.Items), so we can tie the eaches collection in dozens object to be the item source for another UI element. In our case SelectedItem of ParentCombo is actually an instance of a Dozen object. Items property of it gives us eaches collection. Simple, yet very powerful feature.
You can download this sample project here.
Your post has moved the debate forward. Thanks for shainrg!