1

I am using dockpanel to display a list of buttons that are read from an itemsource and want to display them horizontally but it displays them vertically.

I am using the following code:

<DockPanel Name="DockPanel2"  Grid.Row="1"   Visibility="Visible">
            <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="260,50,0,0">
                <ItemsControl ItemsSource="{Binding PageViewModels}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Button Foreground="MidnightBlue"
                            Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                CommandParameter="{Binding }"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
           <ContentControl  Content="{Binding CurrentPageViewModel}"/>
        </DockPanel>

If I use the following code (taking buttons as static list I am able to display the list in a horizontal fashion.

 <DockPanel Name="DockPanel2"  Grid.Row="1"   Visibility="Visible">
            <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="260,50,0,0">
                <Button Content="Button 1" Margin="2" />
                <Button Content="Button 2" Margin="2" />
                <Button Content="Button 3" Margin="2" />
                <Button Content="Button 4" Margin="2" />
                <Button Content="Button 5" Margin="2" />
            </StackPanel>

            <ContentControl  Content="{Binding CurrentPageViewModel}" />
        </DockPanel>

Can someone tell me where am I going wrong.

Thanks, T

user3625024
  • 319
  • 1
  • 2
  • 11

5 Answers5

2

You should use the property ItemsPanelTemplate of the ItemControl and put a StackPanel inside it.

Something like the following:

<DockPanel Name="DockPanel2"  Grid.Row="1"   Visibility="Visible">
            <ItemsControl ItemsSource="{Binding PageViewModels}"
                          DockPanel.Dock="Top">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Foreground="MidnightBlue"
                        Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                            CommandParameter="{Binding }"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
       <ContentControl  Content="{Binding CurrentPageViewModel}"/>
    </DockPanel>

Note, that I have removed the stackPanel just after the dockPanel.

Bartosz
  • 4,406
  • 7
  • 41
  • 80
Guerudo
  • 361
  • 1
  • 7
0

The problem is that an ItemsControl does not generate separate items in the StackPanel, it generates the items in it's own "Panel", therefore you will have to use a StackPanel for the ItemsPanel.

I will provide you with some example code once I've tried it myself.

EDIT: I just hate you guys who simply take other answers and use them as their own, I guess I don't need to add example code...

Staeff
  • 4,994
  • 6
  • 34
  • 58
0

You need to specify the ItemsPanelTemplate of the ItemsControl to be a StackPanel in horizontal orientation. What you have is just a StackPanel that hosts an ItemsControl - the fact that it is horizontally orientated is of no conseqeuence here. So try this:

<ItemsControl ItemsSource="{Binding PageViewModels}">
        <ItemsControl.ItemPanelTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
       </ItemsControl.ItemPanelTemplate>

       <ItemsControl.ItemTemplate ... your existing xaml >
</ItemsControl>
James Lucas
  • 2,452
  • 10
  • 15
0

You have to set the StackPanel as ItemsPanel of ItemsControl.

Example:

    <ItemsControl ....>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation ="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button .... />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
Arie
  • 5,251
  • 2
  • 33
  • 54
0

I found you can just create the element you want add it to a list and then use a VirtualizingStackPanel.

I use this in a foreach loop to turn my enums into a button list.

foreach (MyEnum myenum in(MyEnum[])Enum.GetValues(typeof(MyEnum))){
    Button btn = new Button();
        btn.Name = "This Is Optional";
        btn.Content = "Content";
        btn.Click += CustomCommand;
        btn.CommandParameter = myenum;
        buttonlist.Add(temp);
}

I store my button list in an ObservableCollection.

public ObservableCollection<Button> buttonlist = new ObservableCollection<Button>();

This is the basic way I can execute the command based on the Enum value.

private void CustomCommand(object sender, RoutedEventArgs e)
{
    MyEnum parameter = (MyEnum)(sender as Button).CommandParameter;
}

And Then add them all to your view using a VirtualizingStackPanel.

<ItemsControl ItemsSource="{Binding buttonlist}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

Just sharing this as it seems dynamic and you can use it for any WPF element you can even make a mixed object List and the VirtualizingStackPanel will take care of it.

Tim
  • 89
  • 1
  • 8