I did quite a bit of WPF a couple of years ago but seem to have forgotten everything.
Suppose I have a simple business class, say a TFS workitem.
public class WorkItem
{
public WorkItem(string name, DateTime date)
{
Name = name;
Date = date;
}
public string Name { get; set; }
public DateTime Date { get; set; }
}
Then I have a list of WorkItems, perhaps something like this.
class WiList : ObservableCollection<WorkItem>
{
public WiList () : base()
{
Add(new WorkItem("1", DateTime.Now));
Add(new WorkItem("2", DateTime.Now));
}
}
Then I have a UserControl that represents a WorkItem, something like this.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="WrapPanelItemsControlTest.WorkItemControl"
开发者_如何学Go x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="72" Height="40">
<StackPanel x:Name="LayoutRoot">
<TextBlock x:Name="Name"/>
<TextBlock x:Name="Date"/>
</StackPanel>
The main window contains a WrapPanel to hold the UserControls. My question is, how do I create a WrapPanel that binds to the WiList and displays the WorkItems? I remember doing something like this before, but for the death of me I can't remember how (probably something from Bea Costa's blog). Of course I can't find my old test code anywhere and seem to be expectionally bad at googling for examples.
Any help is appreaciated.
You probably need to use ItemsControl
for this. WrapPanel
can be used as layout panel for the elements of the collection. And if you only need the UserControl
to show properties of one object, then the better choice would be to use a DataTemplate
. Here's some XAML:
<Window.Resources>
<DataTemplate x:Key="WorkItemTemplate" DataType="{x:Type local:WorkItem}">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Date}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl
x:Name="itemsList"
ItemTemplate="{StaticResource WorkItemTemplate}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
And in code-behind bind the ItemsControl
to the collection:
itemsList.ItemsSource = new WIList(); // or wherever the collection comes from
P.S. Initializing ItemsSource
and generally accessing controls from code-behind to bind them to data is not a good practice. You would need a ViewModel (Presenter) class as the DataContext of your window. If you consider staying for some time with WPF my advice is - try to use MVVM.
P.P.S. Don't forget to implement INotifyPropertyChanged
on WorkItem
if you need WPF to keep up with changes of properties' values.
First you'll need to bind an instance of your WiList class to a ItemsControl's ItemsSource and then apply a DataTemplate for your WorkItem.
There's a similar thread here.
You can find out more about the ItemsControl's ItemsPanel here.
精彩评论