Items Binding (ListBox, ComboBox, ItemsControl)

Introduction

Some controls support the dynamic creation of children when their Items property is bound. These include ListBox, ComboBox, and ItemsControl. This page discusses how to dynamically create these items using the Items property.

Items Binding Concepts

Controls which have an Items property automatically create children when an object is added to the Items property. This addition can be explicitly performed by calling Items.Add or can be performed by binding to an observable collection and changing that collection.

Although binding can be performed to any collection, ObservableCollection is commonly used so that the collection can change dynamically, automatically updating the displayed controls. All operations on ObservableCollection are supported including adding, removing, clearing, and reordering.

Binding can be performed to any type which implements INotifyCollectionChanged, so developers familiar with MVVM can use any view model implementation. This document uses Gum's ViewModel for simplicity.

ItemsControl Binding

ItemsControl is similar to ListBox, but it does not have any restrictions on visual types since ItemControl does not support the concept of selection. This makes ItemsControl suitable for general usage.

The following code shows how to bind an ItemsControl to a ViewModel's ObservableCollection:

public class ExampleViewModel : ViewModel
{
    public ObservableCollection<DateTime> Dates
    {
        get;
        private set;
    } = new ObservableCollection<DateTime>();
}

//------------------------------------------

var viewModel = new ExampleViewModel();

var stackPanel = new StackPanel();
stackPanel.AddToRoot();
stackPanel.Anchor(Anchor.Center);

var itemsControl = new ItemsControl();
stackPanel.AddChild(itemsControl);
itemsControl.Width = 200;
itemsControl.BindingContext = viewModel;
itemsControl.SetBinding(
    nameof(itemsControl.Items),
    nameof(viewModel.Dates));

var addButton = new Button();
stackPanel.AddChild(addButton);
addButton.Text = "Add Date";
addButton.Click += (_, _) =>
{
    viewModel.Dates.Add(DateTime.Now);
};
Items added through binding

The FrameworkElementTemplate template can be modified to support creating custom FrameworkElement types as shown in the following code block:

Each item created through the FrameworkElementTemplate is bound to a corresponding item in the Items collection. This means that each FrameworkElement can be further customized through its own binding.

For example, we can create a top-level view model which contains a collection of weapons. Each weapon is displayed with a custom button.

The following code shows the two view models:

Each WeaponViewModel instance is displayed with a new Button instance called ButtonWithSubtext as shown in the following code block:

Finally, these view models and custom button can be used to display weapons in an ItemsControl as shown in the following code block:

ItemsControl displaying weapons using a customized Button

Last updated

Was this helpful?