0

I have a ObservableCollection of custom control objects.

ObservableCollection<MyStatusBar> MyUIObjects = new ObservableCollection<MyStatusBar>();

The custom control is a user control like this

public partial class MyStatusBar : UserControl, INotifyPropertyChanged

What is the easiest way that I can bind my list of controls to a stackpanel so they show up. Currently when I bind them nothing shows up. When I add the controls manually to the StackPanel.Children collection they then show up but I want to do it with binding.

Daniel Armstrong
  • 829
  • 9
  • 22
  • 1
    Please, share your binding and xaml code – Pavel Anikhouski May 26 '20 at 08:21
  • @daniel use itemscontrol to bind custom object and set panel type stackpanel to display the collection of custom objects. – neelesh bodgal May 26 '20 at 09:17
  • 1
    for binding to work `MyUIObjects` has to be [a public *property*, not *field*](https://stackoverflow.com/q/842575/1506454): `public ObservableCollection MyUIObjects {get;} = new ObservableCollection();` – ASh May 26 '20 at 15:29
  • also it is a questionable idea to implement INotifyPropertyChanged in a UserControl. use only DependencyProperties - they have built-in notification support - and much more – ASh May 26 '20 at 15:30

2 Answers2

1

MyStatusBar shouldn't be a UserControl but a POCO:

public class MyStatusBar : INotifyPropertyChanged { ... }

You could then use an ItemsControl to bind to the ObservableCollection<MyStatusBar> and define an ItemTemplate in where you put the UserControl to be rendered for each POCO object:

<ItemsControl ItemsSource="{Binding MyUIObjects}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:MyStatusBarUserControl />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The ItemsPanelTemplate specifies the panel - in this case a StackPanel - that the ItemsPresenter creates for the layout of the items in the ItemsControl.

Note that MyStatusBar and MyStatusBarUserControl are different types. A view model should not create or expose UI elements. It should expose data objects. You are then creating a UI element per data object using the ItemTemplate.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • I tried this solution, but I receive a 26 error: ` ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type` – Vali Maties May 10 '22 at 05:28
0

Please check out the code snippet. Replace Itemcontrol with any itemscontrols' like listbox so on otherwise can u still use Itemscontrol

<ItemsControl ItemsSource="{Binding MyUIObjects}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
neelesh bodgal
  • 632
  • 5
  • 14
  • ItemsControl uses vertical virtualizing StackPanel by default. it doesn't make much sense to explicitely assign `` to ItemsPanel – ASh May 26 '20 at 15:07
  • @ash you are correct. This snippet is just an example of usage how to bind observable collection instead of complete solution. – neelesh bodgal May 26 '20 at 15:18