#1,043 – Using a DockPanel as the Items Panel for a ListBox

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:

1044-001

About Sean
Software developer in the Twin Cities area, passionate about software development and sailing.

One Response to #1,043 – Using a DockPanel as the Items Panel for a ListBox

  1. john Smith says:

    Thank you for your code ^^

Leave a comment