Wpf 如何组织ItemsPanel布局?

Wpf 如何组织ItemsPanel布局?,wpf,Wpf,我有下面的代码,我想显示一系列按钮水平与图像和文本标签,并在该行按钮下面的整个按钮组一个标签。我当前拥有的将按钮显示在一行中,但组标签显示在按钮左侧的同一行中。我可能做错了,但我对自己走了这么远印象深刻。我曾尝试将子ItemsPanel放在StackPanel中,但它没有显示任何按钮-它似乎与父窗口中的集合失去了联系。是否有简单的方法连接此集合并组织按钮下方的标签?我想我的下一次尝试是在孩子的代码隐藏中从父母那里收集数据,并构建一个ItemsSource,然后将其连接到ItemTemplate,

我有下面的代码,我想显示一系列按钮水平与图像和文本标签,并在该行按钮下面的整个按钮组一个标签。我当前拥有的将按钮显示在一行中,但组标签显示在按钮左侧的同一行中。我可能做错了,但我对自己走了这么远印象深刻。我曾尝试将子ItemsPanel放在StackPanel中,但它没有显示任何按钮-它似乎与父窗口中的集合失去了联系。是否有简单的方法连接此集合并组织按钮下方的标签?我想我的下一次尝试是在孩子的代码隐藏中从父母那里收集数据,并构建一个ItemsSource,然后将其连接到ItemTemplate,但我也不知道如何做到这一点

父窗口片段:

<User_Controls:ToolbarGroup GroupLabel="Group 1">
    <User_Controls:ImageButton ButtonText="Test 1"/>
    <User_Controls:ImageButton ButtonText="Test 2"/>
    <User_Controls:ImageButton ButtonText="Test 3"/>
</User_Controls:ToolbarGroup>

子窗口代码:

<ItemsControl x:Class="Fiducia_WPF.User_Controls.ToolbarGroup"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:User_Controls="clr-namespace:Fiducia_WPF.User_Controls" 
    mc:Ignorable="d" 
    Loaded="ItemsControl_Loaded"
    d:DesignHeight="170" d:DesignWidth="320">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" Height="170" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <User_Controls:ImageButton ButtonText="Temp"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <Label Name="lblGroupTitle" Grid.Row="1" Grid.Column="0" Content="Group X" FontSize="16" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Visible" />
</ItemsControl>

我只需要使用一个笔直的网格:

<Grid>
 <Grid.ColumnDefinitions>
   <ColumnDefinition Width="*" />
   <ColumnDefinition Width="*" />
   <ColumnDefinition Width="*" />
 </Grid.ColumnDefinitions>
 <Grid.RowDefinitions>
   <RowDefinition Height="*"/>
   <RowDefinition Height="*"/>
 </Grid.RowDefinitions>
 <Button Grid.Row="0" Grid.Column="0" ... />
 <Button Grid.Row="0" Grid.Column="1" ... />
 <Button Grid.Row="0" Grid.Column="2" ... />
 <Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" />
</Grid>

您应该为您的项目创建一个
控制模板
控制:

<ItemsControl x:Class="Fiducia_WPF.User_Controls.ToolbarGroup" ...>
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <StackPanel>
                <ItemsPresenter/>
                <Label x:Name="lblGroupTitle" Content="Group X" ... />
            </StackPanel>
        </ControlTemplate>
    </ItemsControl.Template>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" Height="170" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <User_Controls:ImageButton ButtonText="Temp"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我知道如何做网格。我不想这样做,因为这个过程将用不同数量的按钮和不同的标签重复大约50次。我还尝试在ItemsPanel周围放置一个网格,这也失去了与原始调用数据的连接。因此一个项目可能有3个按钮,而另一个项目只有2个?你想把3个按钮的行分成3行,把2个按钮的行分成1/2行?每行有多个标签吗?一个在按钮1和2下面,另一个在按钮3下面?如果是这样的话,我认为您必须编写一个自定义的布局面板,因为没有内置的东西可以做到这一点。若我这样做(若我的假设是正确的),那个么我将从网格中派生一个类并添加一些dp,这样我就可以创建可绑定的网格和行定义。这可能是最简单的方法,除非你想从scratchClemens开始:谢谢你的建议。您可能走对了,但当我在UserControl:ToolbarGroup中使用GroupLabel属性时,它没有设置lblGroupTitle内容。首先,我必须在之后添加代码,以使您的代码得以编译。其次,我在子窗口后面有一个GroupLabel属性,它有一个属性集函数,调用var oLabel=this.Template.FindName(“lblGroupTitle”,this)作为标签;但是oLabel是空的。有什么建议吗?克莱门斯:谢谢你的回复。你的建议可能是正确的答案,但它把我弄糊涂了。然而,它给了我另一个可行的想法。我推断,当设置GroupLabel属性时,lblGroupTitle控件还不存在。因此,我将GroupLabel值存储在类属性中。我向ItemsControl加载的事件添加了一个事件处理程序,在该事件处理程序中,我可以找到lblGroupTitle控件并将其文本设置为GroupLabel属性。这可能不是最好的方法,但它是有效的。谢谢
<Label Content="{Binding GroupTitle,
    RelativeSource={RelativeSource AncestorType=User_Controls:ToolbarGroup}}" ... />