C# WPF Bindings and ItemsControls


This entry is part 12 of 18 in the series C# WPF

Often in developing WPF C# programs you will want to bind the controls to one object at a time from a collection of objects. Below is a ComboBox that contains the names of four people. When you select a person in the ComboBox, the program shows that person’s information in the area at the top. In another post there is some information about ComboBoxes. This program has three labels and a combobox inside a stack panel and is shown below.

BindingsItemsControls

In the code-behind, there an array of four Person objects and it assigns the array to the ItemsSource property.

However, first take a look at the following console application. Very similar code is used in the windows application, except for writing to the console.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ArrayOfPerson
{
    class Program
    {
        static void Main(string[] args)  {
            // an array of Person objects
            Person[] people = { new Person( "Shirley", 34, "Green" ),
                new Person( "Roy", 36, "Blue" ),
                new Person( "Isabel", 25, "Orange" ),
                new Person( "Manuel", 27, "Red" ) };
            Console.WriteLine($"{people[1].FirstName}, {people[1].Age}, {people[1].FavoriteColor}");
            // Output: Roy, 36, Blue
            // the array is zero-based so it shows the second one
            Console.ReadKey();
        }
    }
    class Person {
        // some properties
        public string FirstName { get; set; }
        public int Age { get; set; }
        public string FavoriteColor { get; set; }
        // a non-default constructor
        public Person(string fName, int age, string color)
        {
            FirstName = fName;
            Age = age;
            FavoriteColor = color;
        }
    }
}

Here we are using the constructor to set the values of the properties.

Binding

In this example we are using code behind to create the binding and we are using XAML also. In another post there was a simple example of creating a binding using the code behind with a text box as the source and a label as the target. What you typed in the text box was immediately displayed in the label.

<Window x:Class="DataComboBox.MainWindow"
        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:DataComboBox"
        mc:Ignorable="d"
        Title="Data Binding Combo Box" Height="200" Width="325">
    <StackPanel>
        <StackPanel Orientation="Horizontal" Margin="5,10" DataContext=
                    "{Binding ElementName=comboPeople, Path=SelectedItem}">
            <Label Name="lblFName" FontWeight="Bold"/>
            <Label Name="lblAge"/>
            <Label Name="lblColor"/>
        </StackPanel>
        <ComboBox Name="comboPeople" SelectedIndex="0" DisplayMemberPath="FirstName" />
    </StackPanel>
</Window>

The DisplayMemberPath is set to FirstName. This tells the combobox which column to display in the combobox. You could change this to whatever column in the array makes sense. Below is the code behind for this example.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DataComboBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // an array of Person objects
            Person[] people = { new Person( "Shirley", 34, "Green" ),
                new Person( "Roy", 36, "Blue" ),
                new Person( "Isabel", 25, "Orange" ),
                new Person( "Manuel", 27, "Red" ) };
            // comboPeople is the Name of the ComboBox
            comboPeople.ItemsSource = people;

            Binding nameBinding = new Binding("FirstName");
            lblFName.SetBinding(ContentProperty, nameBinding);
            Binding ageBinding = new Binding("Age");
            lblAge.SetBinding(ContentProperty, ageBinding);
            Binding colorBinding = new Binding("FavoriteColor");
            lblColor.SetBinding(ContentProperty, colorBinding);
        }
    }
    class Person
    {
        public string FirstName { get; set; }
        public int Age { get; set; }
        public string FavoriteColor { get; set; }
        public Person(string fName, int age, string color)
        {
            FirstName = fName;
            Age = age;
            FavoriteColor = color;
        }
    }
}

Next Steps

The next things that you would likely want to do is to get the data out of being hard coded in the code-behind. Perhaps the data would be in an xml file or in a relational database table. If the list of data never changed then you could use an array (fixed length) and just load the data from the file into an array of objects. However, if the user was able to add new records or edit records or delete records you would need to use a collection of some sort.

One thing that could be done right away is to move the definition of the class to it’s own file instead of being in the code-behind.

Series Navigation<< C# WPF ComboBox ControlC# WPF Styles >>