#1,043 – Using a DockPanel as the Items Panel for a ListBox
April 3, 2014 1 Comment
You can replace the default StackPanel used as the items panel for a ListBox with any other panel element. Below is an example of displaying some news stories in a DockPanel.
Assume that we have a NewsStory class as follow:
public class NewsStory { public string Story { get; set; } public Brush Color { get; set; } public Dock Dock { get; set; } public double Rotate { get; set; } public NewsStory(string story, Color color, Dock dock, double rotate) { Story = story; Color = new SolidColorBrush(color); Dock = dock; Rotate = rotate; } public override string ToString() { return Story; } }
We can then create a collection of NewsStory items that we’ll bind to. Notice that we create a spiral pattern by setting consecutive Dock properties to Bottom/Left/Top/Right. We also use the Angle property to rotate every other element.
public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); this.DataContext = this; Stories = new ObservableCollection<NewsStory> { new NewsStory("Diaper Market Bottoms Out", Colors.AliceBlue, Dock.Bottom, 0.0), new NewsStory("Antique Stripper to Display Wares", Colors.AntiqueWhite, Dock.Left, -90.0), new NewsStory("Cancer Society Honors Marlboro Man", Colors.Aqua, Dock.Top, 0.0), new NewsStory("War Dims Hope for Peace", Colors.Aquamarine, Dock.Right, -90.0) // more entries go here.. }; RaisePropertyChanged("Stories"); } public ObservableCollection<NewsStory> Stories { get; protected set; } // INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = delegate { }; private void RaisePropertyChanged(string propName) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } }
In XAML, we set the ItemContainerStyle to do the docking and specify a DockPanel as the ItemsPanel.
<ListBox ItemsSource="{Binding Stories}"> <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="DockPanel.Dock" Value="{Binding Dock}"/> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> <Setter Property="VerticalContentAlignment" Value="Stretch"/> </Style> </ListBox.ItemContainerStyle> <ListBox.ItemsPanel> <ItemsPanelTemplate> <DockPanel IsItemsHost="True"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Label Content="{Binding Story}" Background="{Binding Color}"> <Label.LayoutTransform> <RotateTransform Angle="{Binding Rotate}"/> </Label.LayoutTransform> </Label> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Here’s what the end result looks like:
Thank you for your code ^^