【问题标题】:How To Organize ItemsPanel Layout?如何组织 ItemsPanel 布局?
【发布时间】:2015-07-17 20:38:03
【问题描述】:

我有下面的代码,我想在其下方显示一系列带有图像和文本标签的按钮,并在该行按钮下方显示整个按钮组的标签。我目前拥有的内容是连续显示按钮,但组标签显示在按钮左侧的同一行中。我可能做错了,但我对我能走到这一步印象深刻。我尝试将 Child ItemsPanel 放在 StackPanel 中,但随后它没有显示任何按钮 - 它似乎与父窗口中的集合失去了联系。有没有一种简单的方法可以连接这个集合并组织按钮下方的标签?我想我的下一个尝试是在孩子的代码隐藏中从父级收集数据并构建一个 ItemsSource,然后我将连接到 ItemTemplate,但我也不知道该怎么做。

父窗口sn-p:

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

【问题讨论】:

    标签: wpf


    【解决方案1】:

    您应该为您的 ItemsControl 创建一个ControlTemplate

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

    设置lblGroupTitle 标签的内容可能最好通过将其绑定到 ToolbarGroup 控件的属性来完成:

    <Label Content="{Binding GroupTitle,
        RelativeSource={RelativeSource AncestorType=User_Controls:ToolbarGroup}}" ... />
    

    【讨论】:

    • 克莱门斯:谢谢你的建议。您可能在正确的轨道上,但是当我使用 UserControl:ToolbarGroup 中的 GroupLabel 属性时,它没有设置 lblGroupTitle 内容。首先,我必须在 之后添加 才能编译您的代码。其次,我在子窗口后面有一个 GroupLabel 属性,它有一个属性设置函数,调用 var oLabel = this.Template.FindName("lblGroupTitle", this) as Label;但 oLabel 为空。有什么建议吗?
    • 克莱门斯:感谢您的回复。您的建议可能是正确的答案,但它让我感到困惑。然而,它给了我另一个可行的想法。我推断当设置 GroupLabel 属性时,lblGroupTitle 控件还不存在。所以我将 GroupLabel 值存储在类属性中。我向 ItemsControl Loaded 事件添加了一个事件处理程序,在该事件处理程序中我可以找到 lblGroupTitle 控件并将其文本设置为 GroupLabel 属性。这可能不是最好的方法,但它确实有效。谢谢。
    【解决方案2】:

    我会直接使用一个向上的网格:

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

    【讨论】:

    • 我知道如何做一个网格。我不想这样做,因为这个过程将重复大约 50 次,使用不同数量的按钮和不同的标签。我还尝试在 ItemsPanel 周围放置一个网格,这也失去了与原始调用数据的连接。
    • 那么一个项目可能有 3 个按钮而另一个项目只有 2 个?并且您希望 3 按钮行拆分为 3 行,而 2 按钮行拆分为 1/2?你要每行有多个标签吗?一个说在按钮 1 和 2 下,另一个在 3 下?如果是这样,我认为您必须编写一个自定义布局面板,因为没有内置任何东西可以做到这一点。如果我这样做(如果我的假设是正确的),那么我将从 Grid 派生一个类并添加一些 DP,以便我可以进行可绑定的网格和行定义。除非您想从头开始,否则这可能是最简单的方法
    猜你喜欢
    • 1970-01-01
    • 2014-08-24
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多