Reputation: 16268
After loading data from a database (let's say we loaded Courses), I want to show them in a list. I've read you can add dynamically content by using UserControl
but the examples are specifically to change content dynamically, not to present a list of results.
What I want is to create a XAML template and instantiate it once per list item, and add it to the list (in other words, adding it to a StackedPanel
). How can I achieve this? Also, should I use a Page
or a UserControl
?
Upvotes: 0
Views: 2033
Reputation: 33506
This is exactly what were ListBox
and ItemsControl
controls created. ListBox is enhanced version of ItemsControl, so I'll only talk about the latter, basic one.
ItemsControl
contains a dependency property called ItemsSource
. Pass a collection there, and the ItemsControl will generate a "panel" filled with "views" of the items taken from that source.
By default, ItemsControl uses a StackPanel as the panel, but you can change it if you want by the ItemPanel
property.
By default, ItemsControl uses a default WPF template matching to generate and present a view for each items. However, you can specifically use an ItemTemplate
property to set a DataTemplate
that will tell how the view should look like.
Example:
<!-- simple vertical/StackPanel list -->
<ItemsControl ItemsSource="{Binding MyItems}">
<ItemsControl.ItemTemplate>
<!-- the template of a single Item -->
<!-- note that I'm setting it here explicitely -->
<!-- but the ItemTemplate prop could have been bound, resourcized, etc -->
<DataTemplate>
<Border BorderThickness="1">
<!-- reads a ShoeSize from the items from MyItems -->
<TextBlock Text="{Binding ShoeSize}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- simple horizontal/StackPanel list -->
<ItemsControl ItemsSource="{Binding MyItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1">
<TextBlock Text="{Binding ShoeSize}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- you can use any panel and any itemtemplate -->
<ItemsControl ItemsSource="{Binding MyXYPoints}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- any Panel is OK! even plain canvas -->
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- just remember that in canvas there's no autolayout -->
<!-- so you need to set the coords on each item! -->
<Ellipse Width="2" Height="2"
Canvas.Left="{Binding PositionX}"
Canvas.Top="{Binding PositionY}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ListBox
is in essence the same control, but provides you with some 'default' goodies like ability to scroll (with virtualization) the items if there are too many, select an item, and so on. You can get those features from ItemsControl, but you'd need to implement or at least configure them by yourself. ListBox just has it already done. But is definitely "heavier" than ItemsControl, so pick what fits best.
Anyways.. I've written that just because I was in sucha mood today. But you really need to read about ItemsControl and Bindings more. In WPF, you almost never place things on the UI "manually from code". I actually shouldn't write as much because experts already covered all of that.. Please Do Read this excellent series of articles by Dr.Wpf. Especially the "I" chapter, since it relates exactly to what you were asking about, but I really recommend reading them all. They are somewhat detailed, a bit too much for some readers, but they get you much needed overview of what great tools you have at hand.
Upvotes: 3