Friday, October 03, 2008

Simple Data Binding Example in WPF

There are two list boxes in my form. One list box should retrieve values from "Roles" property while another list box should show the items that are selected from the roles list box. You can do something like this in WPF very easily, provided you understand data binding. Here is how we do it.

The listbox should first bind to "Roles" a property we define in the code-behind of the window. So the items property is bound as
<ListBox ItemsSource="{Binding Roles}" SelectionMode="Multiple" Name="roles"/>

But where does the framework look for "Roles"?
It first looks in the DataContext of the roles listbox. If it is not found, then it goes up to the parent and looks for its DataContext. In my example, the parent would be a StackPanel whose datacontext is set to "this" in constructor as shown.
public Window1()
{
           InitializeComponent();
           Roles = new List<string>() { "User", "Super User", "Lame User", "Yourself" };
           grid.DataContext = this;
}

Also observe, the Roles property has been created in the constructor. But the roles property has to be a DependencyProperty, if the data binding has to work properly.
public static readonly DependencyProperty RolesProperty =
        DependencyProperty.Register("Roles", typeof(List<string>), typeof(Window1));

        public List<string> Roles
        {
            get
           
{
                return (List<string>)GetValue(RolesProperty);
            }
            set
           
{
                SetValue(RolesProperty, value);
            }
        }

Now, let us look at the second listbox. The requirement is that the items inside the second listbox has to be pulled from the first list box. So its ItemsSource property has to bind with the "SelectedItems" property of roles listbox. Below, I show another way to binding without using Binding Expressions(" {} "). Instead we use Object Element "Binding" to perform the databinding.

<ListBox>
<
ListBox.ItemsSource>
<
Binding>
<
Binding.ElementName>roles</Binding.ElementName>
<
Binding.Path>SelectedItems</Binding.Path>
</
Binding>
</
ListBox.ItemsSource>
</
ListBox>


Note that SelectedItems is already a depedency property.



The complete XAML is shown.



<StackPanel Name="grid">
<
ListBox ItemsSource="{Binding Roles}" SelectionMode="Multiple" Name="roles">
</
ListBox>
<
Label>Selected Items</Label>
<
ListBox>
<
ListBox.ItemsSource>
<
Binding>
<
Binding.ElementName>roles</Binding.ElementName>
<
Binding.Path>SelectedItems</Binding.Path>
</
Binding>
</
ListBox.ItemsSource>
</
ListBox>
</
StackPanel>


Note that, we cannot set SelectedItems property of a listbox in XAML, as the compiler complains about the property being read-only.

As I learn more about DataBinding, I would post the stuff here.

No comments: