How can I use data binding in WPF to create a new user control for each item in the list?

I have a list of objects. For each item in the list, I want to create a new user control associated with this item. From what I read, doing it programmatically is bad practice with WPF (and also less simple), so I should use data binding instead. The problem is that I cannot figure out how to do this. I do not know the contents of the list (only the type) at compile time, so I cannot create and link to XAML for each element. Google and MSDN have no answers, maybe I'm thinking about it wrong? What do I need to do?

thanks

EDIT: To clarify, I'm trying to create my own music rating software, something like Rosegarden. The list will contain all measures, and usercontrols - their visual representation.

+4
source share
3 answers

A more general approach than the suggestion of Julien Leboscan (and the one that will work when the list of elements contains objects of more than one data type):

Create a DataTemplate that will be used when representing the element of type (s) in your list, for example:

 <DataTemplate DataType="local:Measure"> <local:MeasureUserControl DataContext="{Binding}"/> </DataTemplate> 

Use ItemsControl to represent items:

 <ItemsControl ItemsSource="{Binding MeasureList}"/> 

You can set the ItemsPanel ItemsControl property to ItemsPanelTemplate to determine how it will expose user controls, for example:

 <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> 

This approach is usually preferable to using a ListBox if you do not want to use the ListBox functions, for example. its default boundaries and selection behavior.

+5
source

You can use the standard ListBox style of the custom element:

Somewhere in the resources:

 <Style TargetType="{x:Type ListBoxItem}" x:Key="CustomItemStyle"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <yourns:YourControl /> </ControlTemplate> </Setter.Value> </Setter> </Style> 

In your window / page / usercontrol:

 <ListBox ItemsSource="{Binding ...}" ItemContainerStyle="{StaticResource CustomItemStyle}" /> 

Since your objects will be bound to a list, an implicit ListBoxItem will be created for each object, and its DataContext set to the object so that you can use the bindings in YourControl without any problems.

+4
source

All of the above answers work, but I will leave everything as I do in my application. I am implementing an MVVM architecture that takes advantage of these WPF features. This is the UserControl that I use, which has an ItemsControl populated with elements of a certain type:

 <UserControl x:Class="Controls.StepView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:Controls" Background="Transparent"> <UserControl.Resources> <DataTemplate DataType="{x:Type my:ParameterViewModel}" > <my:ParameterView HorizontalAlignment="Stretch" Margin="25 0 0 0"/> </DataTemplate> </UserControl.Resources> <Grid> <ItemsControl Name="stkStepContent" ItemsSource="{Binding Parameters}" /> </Grid> </UserControl> 

Let me explain the code to you. in the DataTemplate section, I say that I want to render objects of the ParameterViewModel class using the UserControl ParameterView. The ItemsSource property of my ItemsControl bound to a List<ParameterViewModel> . When an ItemsControl triggered for each ParameterViewModel in the List, it will create a ParameterView and set its DataContext to the ParameterViewmodel, this is a rendering. I found that this architectural pattern is the most intuitive for me to create WPF applications.

+3
source

Source: https://habr.com/ru/post/1311363/


All Articles