在停靠面板中水平排列动态按钮列表

Arrange dynamic list of buttons horizontally in dockpanel

我正在使用停靠面板显示从 itemsource 读取的按钮列表,并希望水平显示它们,但它却垂直显示。

我正在使用以下代码:

<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>

如果我使用以下代码(将按钮作为静态列表,我能够以水平方式显示列表。

 <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>

谁能告诉我哪里出错了。

谢谢, T

问题是 ItemsControl 不会在 StackPanel 中生成单独的项目,而是在它自己的 "Panel" 中生成项目,因此您将不得不使用 StackPanelItemsPanel.

我会在自己尝试后提供一些示例代码。

编辑:我只是讨厌你们那些简单地接受其他答案并将其用作自己的答案的人,我想我不需要添加示例代码...

您需要将ItemsControl 的ItemsPanelTemplate 指定为水平方向的StackPanel。您所拥有的只是一个托管 ItemsControl 的 StackPanel - 它是水平方向的事实在这里没有任何意义。所以试试这个:

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

       <ItemsControl.ItemTemplate ... your existing xaml >
</ItemsControl>

您必须将 StackPanel 设置为 ItemsControlItemsPanel

示例:

    <ItemsControl ....>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation ="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button .... />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

您应该使用 ItemControl 的 属性 ItemsPanelTemplate 并在其中放置一个 StackPanel。

类似于以下内容:

<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>

请注意,我删除了 dockPanel 之后的 stackPanel

我发现您可以只创建您想要的元素,将其添加到列表中,然后使用 VirtualizingStackPanel。

我在 foreach 循环中使用它来将我的枚举转换为按钮列表。

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);
}

我将我的按钮列表存储在一个 ObservableCollection 中。

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

这是我可以根据枚举值执行命令的基本方法。

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

然后使用 VirtualizingStackPanel 将它们全部添加到您的视图中。

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

只是共享它,因为它看起来是动态的,您可以将它用于任何 WPF 元素,您甚至可以创建一个混合对象列表,VirtualizingStackPanel 会处理它。