Intersoft ClientUI Documentation
Walkthrough: Bind to Parent Property in XAML using FindAncestor

This walkthrough shows how to use FindAncestor mode to bind the elements inside ItemTemplate of a UXListBox to UXListBoxItem as their ancestor.

In this walkthrough, you perform the following tasks:

Prerequisites

You need the following components to complete this walkthrough:

Creating a new ClientUI MVVM Application Project

The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.

To create the ClientUI MVVM Application project

  1. Start Visual Studio 2010.
  2. Create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template. To learn more, see Walkthrough: Create New Intersoft ClientUI MVVM Application Template.
  3. In project reference, add System.Xml.Linq.dll. This assembly is required to perform LINQ query to xml data.

To add the resources file

  1. In your project, create new folder with name Assets.
  2. In Assets folder, create new folder with name Chairs .
  3. In Chairs folder, copy the images from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.ClientUIFramework\SampleData\SampleDataSource\SampleDataSource_Files]

Creating Model Class

This section shows how to create the Chair model class that represents the data entity used in this walkthrough.

To create Chair Model Class

  1. Create a model class that inherits from ModelBase class under the Models folder, named it Chair.cs.
  2. Add Name and Image property to Chair model class by defining the backing field along with complete getter and setter in the property. In the setter property, you need to call the OnPropertyChanged method after the backing field is assigned to the new value.
    C#
    Copy Code
    private string _name;
    private string _image;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }
    
    public string Image
    {
        get
        {
            return _image;
        }
        set
        {
            if (_image != value)
            {
                _image = value;
                OnPropertyChanged("Image");
            }
        }
    }
  3. Create LoadData method. This method is used to load the Chair data. 
    C#
    Copy Code
    public static ObservableCollection<Chair> LoadData()
    {
        ObservableCollection<Chair> data = new ObservableCollection<Chair>();
        data.Add(new Chair() { Name = "A. Datum Corporation", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image01.png" });
        data.Add(new Chair() { Name = "Adventure Works", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image02.png" });
        data.Add(new Chair() { Name = "Adventure Works", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image03.png" });
        data.Add(new Chair() { Name = "Alpine Ski House", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image04.png" });
        data.Add(new Chair() { Name = "Baldwin Museum of Science", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image05.png" });
        data.Add(new Chair() { Name = "Blue Yonder Airlines", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image01.png" });
        data.Add(new Chair() { Name = "City Power & Light", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image02.png" });
        data.Add(new Chair() { Name = "Coho Vineyard", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image03.png" });
        data.Add(new Chair() { Name = "Coho Winery", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image04.png" });
        data.Add(new Chair() { Name = "Coho Vineyard & Winery", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image05.png" });
    
        return data;
    }
  4. Create Chair model class Constructor.
    C#
    Copy Code
    public Chair()
    {
    }

Creating the View

This section steps you through the process of creating a page that uses UXListBox and UXHyperlinkButton. The UXListBox is used to display a collection of Chair data.

To create the ChairView

  1. Right click on Views folder, and add new item. Select Intersoft UXPage as the template page. Named it ShowChairs.xaml.
    For more information on how to add a new item in Visual Studio, see Walkthrough: Add New Item such as Page, Dialog Box and Window in VS 2010
  2. Double click on ShowChairs.xaml and add UXListBox control. Set the following property:
    Property Value
    Height 125
    Width 200
    ItemContentType ContentAndImage
    ItemImageHeight 32
    ItemImageWidth 32
    HorizontalScrollBarVisibility Disabled
    XAML
    Copy Code
    <Grid x:Name="LayoutRoot">
        <Intersoft:UXListBox Height="125" Width="200" ItemContentType="ContentAndImage" ItemImageHeight="32" ItemImageWidth="32" HorizontalScrollBarVisibility="Disabled">
            <Intersoft:UXListBoxItem Content="UXListBoxItem" />
            <Intersoft:UXListBoxItem Content="UXListBoxItem" />
        </Intersoft:UXListBox>
    </Grid>

  3. Clear the content of UXListBox and create a new ItemTemplate.
    XAML
    Copy Code
    <Intersoft:UXListBox Height="125" Width="200" ItemContentType="ContentAndImage" ItemImageHeight="32" ItemImageWidth="32" HorizontalScrollBarVisibility="Disabled">
        <Intersoft:UXListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock/>
                    <StackPanel Orientation="Horizontal">
                        <Intersoft:UXHyperlinkButton Content="Details" IsToggleButton="False" Foreground="Navy"/>
                        <Intersoft:UXHyperlinkButton Content="Order" IsToggleButton="False" Foreground="Navy" Margin="8,0,0,0"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </Intersoft:UXListBox.ItemTemplate>
    </Intersoft:UXListBox>

Creating the ViewModel

This section steps you through the process of creating a ViewModel class that contains the properties to describe the View that you created in the previous section. The ViewModel defines the Chairs property to represent an observable collection of Chair model.

To create the ShowChairViewModel

  1. Create ShowChairsViewModel that inherit from ViewModelBase.
    C#
    Copy Code
    ...
    public class ShowChairsViewModel : ViewModelBase
    {
    
        public ShowChairsViewModel()
        {
            this.Chairs = Chair.LoadData();
        }
    
    
        private ObservableCollection<Chair> _chairs;
        public ObservableCollection<Chair> Chairs
        {
            get { return this._chairs; }
            set
            {
                if (this._chairs != value)
                {
                    this._chairs = value;
                    this.OnPropertyChanged("Chairs");
                }
            }
        }
    }
    ...

Binding to UXListBoxItem's using ClientUI Binding Framework

This section show how to bind the ViewModel that was created in the previous section to the View.

In the previous sections, you have learned how to create the Model and ViewModel classes, as well as the View that contains the user interface and controls used in this walkthrough. This section shows how to instantiate the ViewModel in the XAML page and bind the UI elements to the properties in the ViewModel such as the data context.

This section show how to bind the Visibility property of elements inside ItemTemplate property of UXListBox to IsSelected property of UXListBoxItem as their ancestor. The binding is performed using FindAncestor mode of ClientUI Binding Framework.

To bind the ViewModel pattern

  1. Declare the namespace that maps to the ShowChairsViewModel in ShowChairs.xml. Instantiate a new instance of the ShowChairsViewModel class in the UXPage resources and name it ShowChairsViewModel
    XAML
    Copy Code
    ..
    <Intersoft:UXPage 
            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:ViewModels="clr-namespace:ClientUIMVVMApp2.ViewModels"
            mc:Ignorable="d"
            xmlns:Intersoft="http://intersoft.clientui.com/schemas"
            x:Class="ClientUIMVVMApp2.Views.ShowChairs" 
            Title="ShowChairs Page"
            d:DesignWidth="640" d:DesignHeight="480">
    ..      
    <Intersoft:UXPage.Resources>
        <ViewModels:ShowChairsViewModel x:Key="ShowChairsViewModel"></ViewModels:ShowChairsViewModel>
    </Intersoft:UXPage.Resources>
    ...
  2. Set DataContext of LayoutRoot to ShowChairsViewModel.
    XAML
    Copy Code
    ...
    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ShowChairsViewModel}">
        <Intersoft:UXListBox Height="125" Width="200" ImageMemberPath="Image" ItemContentType="ContentAndImage" ItemImageHeight="32" ItemImageWidth="32" HorizontalScrollBarVisibility="Disabled">
            <Intersoft:UXListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock/>
                        <StackPanel Orientation="Horizontal">
                            <Intersoft:UXHyperlinkButton Content="Details" IsToggleButton="False" Foreground="Navy"/>
                            <Intersoft:UXHyperlinkButton Content="Order" IsToggleButton="False" Foreground="Navy" Margin="8,0,0,0"/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </Intersoft:UXListBox.ItemTemplate>
        </Intersoft:UXListBox>
    </Grid>
    ...
  3. Bind ItemsSource property of UXListBox, and also set ImageMemberPath property to Image.
    XAML
    Copy Code
    ...
    <Intersoft:UXListBox ItemsSource="{Binding Chairs}" Height="125" Width="200" ImageMemberPath="Image" ItemContentType="ContentAndImage" ItemImageHeight="32" ItemImageWidth="32" HorizontalScrollBarVisibility="Disabled">
        <Intersoft:UXListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock/>
                    <StackPanel Orientation="Horizontal">
                        <Intersoft:UXHyperlinkButton Content="Details" IsToggleButton="False" Foreground="Navy"/>
                        <Intersoft:UXHyperlinkButton Content="Order" IsToggleButton="False" Foreground="Navy" Margin="8,0,0,0"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </Intersoft:UXListBox.ItemTemplate>
    </Intersoft:UXListBox>
    ...

  4. Bind the Text property of TextBlock control which defined inside ItemTemplate of UXListBox to Name property of Chair model.
    XAML
    Copy Code
    ...
    <Intersoft:UXListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}"/>
                <StackPanel Orientation="Horizontal">
                    <Intersoft:UXHyperlinkButton Content="Details" IsToggleButton="False" Foreground="Navy"/>
                    <Intersoft:UXHyperlinkButton Content="Order" IsToggleButton="False" Foreground="Navy" Margin="8,0,0,0"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </Intersoft:UXListBox.ItemTemplate>
    ...
  5. Declare Visibility converter in the Intersoft:UXPage Resources. This converter is used to convert the value of IsSelected property of UXListBox to Visibility property.
    XAML
    Copy Code
    ...
        <Intersoft:UXPage.Resources>
            <ViewModels:ShowChairsViewModel x:Key="ShowChairsViewModel"></ViewModels:ShowChairsViewModel>
            <Intersoft:VisibilityConverter x:Key="VisibilityConverter"/>
        </Intersoft:UXPage.Resources>
    ...
  6. Bind the Visibility property of element inside ItemTemplate of UXListBox to IsSelected property  of UXListBoxItem using FindAncestor mode of ClientUI Binding Framework.
    XAML
    Copy Code
    ...
    <Intersoft:UXListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}"/>
                <StackPanel Orientation="Horizontal">
                    <Intersoft:BindingFramework.Binding>
                        <Intersoft:BindingDescriptor TargetProperty="Visibility" SourceProperty="IsSelected" Mode="FindAncestor" AncestorType="UXListBoxItem" Converter="{StaticResource VisibilityConverter}"></Intersoft:BindingDescriptor>
                    </Intersoft:BindingFramework.Binding>
                    <Intersoft:UXHyperlinkButton Content="Details" IsToggleButton="False" Foreground="Navy"/>
                    <Intersoft:UXHyperlinkButton Content="Order" IsToggleButton="False" Foreground="Navy" Margin="8,0,0,0"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </Intersoft:UXListBox.ItemTemplate>
    ...
  7. Make sure that in App.xaml.cs, the Application StartUp should be set to ShowChairs.
    C#
    Copy Code
    ...
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        this.RootVisual = new Views.ShowChairs();
    }
    ...
  8. Save, build and run the project. Notice that the Visibility of each UXHyperlinkButton will be set based on the IsSelected property value of the UXListBoxItem.

In this walkthrough, you have learned how to use BindingDescriptor to declaratively bind an object such as ViewModel to a parent property of a control in XAML. For more information about ClientUI Binding Framework, see Data Binding Overview.

Complete Code Listing

This section lists the complete code used in this walkthrough.

Chair.cs

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ClientUIMVVMApp2.ViewModels;
using System.Xml.Linq;
using System.Collections.ObjectModel;

namespace ClientUIMVVMApp2.Models
{
    public class Chair : ModelBase
    {
        #region Constructor

        public Chair()
        {
        }

        #endregion

        #region Fields

        private string _name;
        private string _image;

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        public string Image
        {
            get
            {
                return _image;
            }
            set
            {
                if (_image != value)
                {
                    _image = value;
                    OnPropertyChanged("Image");
                }
            }
        }

        public override string ToString()
        {
            return this.Name;
        }

        #endregion

        #region Methods

        public static ObservableCollection<Chair> LoadData()
        {
            ObservableCollection<Chair> data = new ObservableCollection<Chair>();
            data.Add(new Chair() { Name = "A. Datum Corporation", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image01.png" });
            data.Add(new Chair() { Name = "Adventure Works", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image02.png" });
            data.Add(new Chair() { Name = "Adventure Works", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image03.png" });
            data.Add(new Chair() { Name = "Alpine Ski House", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image04.png" });
            data.Add(new Chair() { Name = "Baldwin Museum of Science", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image05.png" });
            data.Add(new Chair() { Name = "Blue Yonder Airlines", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image01.png" });
            data.Add(new Chair() { Name = "City Power & Light", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image02.png" });
            data.Add(new Chair() { Name = "Coho Vineyard", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image03.png" });
            data.Add(new Chair() { Name = "Coho Winery", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image04.png" });
            data.Add(new Chair() { Name = "Coho Vineyard & Winery", Image = "/ClientUIMVVMApp2;component/Assets/Chairs/image05.png" });

            return data;
        }

        #endregion
    }
}

ShowChairs.xaml

XAML
Copy Code
<Intersoft:UXPage 
        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:ViewModels="clr-namespace:ClientUIMVVMApp2.ViewModels"
        mc:Ignorable="d"
        xmlns:Intersoft="http://intersoft.clientui.com/schemas"
        x:Class="ClientUIMVVMApp2.Views.ShowChairs" 
        Title="ShowChairs Page"
        d:DesignWidth="640" d:DesignHeight="480">
        
    <Intersoft:UXPage.Resources>
        <ViewModels:ShowChairsViewModel x:Key="ShowChairsViewModel"></ViewModels:ShowChairsViewModel>
        <Intersoft:VisibilityConverter x:Key="VisibilityConverter"/>
    </Intersoft:UXPage.Resources>
    
        <Grid x:Name="LayoutRoot" DataContext="{StaticResource ShowChairsViewModel}">
        <Intersoft:UXListBox ItemsSource="{Binding Chairs}" Height="125" Width="200" ImageMemberPath="Image" ItemContentType="ContentAndImage" ItemImageHeight="32" ItemImageWidth="32" HorizontalScrollBarVisibility="Disabled">
            <Intersoft:UXListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Name}"/>
                        <StackPanel Orientation="Horizontal">
                            <Intersoft:BindingFramework.Binding>
                                <Intersoft:BindingDescriptor TargetProperty="Visibility" SourceProperty="IsSelected" Mode="FindAncestor" AncestorType="UXListBoxItem" Converter="{StaticResource VisibilityConverter}"></Intersoft:BindingDescriptor>
                            </Intersoft:BindingFramework.Binding>
                            <Intersoft:UXHyperlinkButton Content="Details" IsToggleButton="False" Foreground="Navy"/>
                            <Intersoft:UXHyperlinkButton Content="Order" IsToggleButton="False" Foreground="Navy" Margin="8,0,0,0"/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </Intersoft:UXListBox.ItemTemplate>
        </Intersoft:UXListBox>
    </Grid>
</Intersoft:UXPage>

ShowChairsViewModel.cs

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ClientUIMVVMApp2.Models;

namespace ClientUIMVVMApp2.ViewModels
{
    public class ShowChairsViewModel : ViewModelBase
    {

        public ShowChairsViewModel()
        {
            this.Chairs = Chair.LoadData();
        }


        private ObservableCollection<Chair> _chairs;
        public ObservableCollection<Chair> Chairs
        {
            get { return this._chairs; }
            set
            {
                if (this._chairs != value)
                {
                    this._chairs = value;
                    this.OnPropertyChanged("Chairs");
                }
            }
        }
    }
}
See Also

Concepts

Other Resources