Home > Software design >  WPF binding to a number of objects only known at runtime
WPF binding to a number of objects only known at runtime

Time:11-09

I'm trying to understand the limits of binding in WPF (if any). I understand how binding to a pre-defined number of objects in XAML works, e.g.:

<Grid>
   <Grid.RowDefinitions>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="Auto"/>
   </Grid.RowDefinitions>

   <Grid.ColumnDefinitions>
       <ColumnDefinition/>
       <ColumnDefinition/>
   </Grid.ColumnDefinitions>

   <TextBlock Text="{Binding MyText}" Grid.Row="1" Grid.Column="0"/>
</Grid>

(I used TextBlock just as an example, it could have been a Button or any other element) Now, suppose that, instead of a single TextBlock, I need to display a number of them, but the exact number will only be known at run-time, together with the text to be written in each TextBlock (and possibly other attributes I may want to bind). Is this something that can be achieved in practice?

CodePudding user response:

To display multiple items in WPF, you would typically use the base ItemsControl class or one of the classes that derives from it. Here is a diagram of the inheritance hierarchy, you can use ItemsControl when all you need is basic functionality and one of its derived classes when you need more:

enter image description here

ItemsControl and its children provide an ItemsSource attribute that allows you to bind your collection (usually an ObservableCollection). However, for user-defined types, you will also need to provide a data template to tell the control how to display the contents.

For example, say you had a simple class like the following:

public class Message
{
    public string MyText { get; set; }
}

And you create a list of them (in your case you would populate the list at run time):

Messages = new List<Message>
{
    new Message { MyText = "SomeText1" },
    new Message { MyText = "SomeText2" },
    new Message { MyText = "SomeText3" },
};

You could display them all using the following xaml:

<ItemsControl ItemsSource="{Binding Messages}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding MyText}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

In side the DataTemplate you would add the controls you use to display the properties of your type and bind to them.

NOTES

Please note that the example above is the bare bones implementation just to show how to get started. Once you get more advanced, you may need to implement change notifications for your properties (i.e. INotifyPropertyChanged) and also for adding/removing items for your collection, etc.

  • Related