【问题标题】:WrapPanel not wrapping contentWrapPanel 不包装内容
【发布时间】:2017-05-24 04:27:03
【问题描述】:

我在用户控件中有以下 xaml 代码。

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" />
                <ColumnDefinition Width="*" MinWidth="50"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="scEmails">
                <ItemsControl Focusable="False" ItemTemplate="{StaticResource UserDataTemplate}">
                    <ItemsControl.Items>
                        <system:String>123</system:String>
                        <system:String>123</system:String>
                        <system:String>123</system:String>
                        <system:String>123</system:String>
                        <system:String>12eee3</system:String>
                        <system:String>123eee</system:String>
                        <system:String>123fefef</system:String>
                    </ItemsControl.Items>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </ScrollViewer>
            <TextBox Grid.Column="1" TextWrapping="NoWrap" Margin="0,0,0,0"  VerticalAlignment="Center" PreviewKeyDown="txtAuto_PreviewKeyDown" MinWidth="50" />
        </Grid>

在这里,我有一组项目要显示在文本框的左侧。渲染要求是:

  1. 如果没有项目或项目很少,让项目占据所需的空间。
  2. 如果项目太多,则项目应换行到下一行并展开控件的Height,以确保文本框获得 50 或更多像素宽度,除非这是不可能的(即有一个项目会占用太多空间)
  3. 如果行数过多(即超过MaxHeight 属性设置的限制),则显示垂直滚动条。
  4. 在任何情况下,文本框都应保留所有左侧的空间(在右侧!)。

我使用ScrollViewer 来实现#3,并使用WrapPanel 来实现#2。但是上面的代码并没有给出想要的结果。在设计模式下看起来像(项目模板是Border 内的TextBlock,在这里不重要)

它不满足要求,因为它没有包装。

我能做些什么来解决?

更新

如果我在 Raviraj Palvankar 的答案中应用代码并删除所有项目,则设计模式下的布局如下

但是,所需的输出(根据需求条款 #4)是

我的原始代码在哪里可以正常运行(尽管不符合其他要求)

【问题讨论】:

  • ItemsControl 所在列的宽度为 auto,为 Grid 的第一列提供 MaxWidth 或 Width,然后它应该可以工作。
  • 对。但由于这是一个用户控件,MaxWidth 或 Width 应由其容器控制,而不是硬编码。有什么想法吗?
  • 然后将第一列更改为“*”,将另一列更改为“Auto”,WrapPanel 才能工作,您必须至少在容器内定义一个固定宽度,否则它将从哪里换行?
  • 正如我在问题中指定的,文本框的最小宽度为 50(像素),这指定了何时换行。我已经尝试像你说的那样交换它们,但是结果不符合要求 - 文本框将不再获取所有可用空间。
  • 是的,但是 TextBox 不是 ItemsControl 的一部分,并且您希望 ItemsControl 内的 Items 进行换行,这意味着您必须修复控件内部而不是外部控件的宽度,因为你想包装物品。

标签: wpf layout wrappanel


【解决方案1】:

这是没有 ItemTemplate 的代码,因此看起来像这样。我添加了更多字符串以表明它确实可以换行。

<Grid Grid.Column="1" Grid.Row="3">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" MinWidth="50"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="scEmails">
            <ItemsControl Focusable="False" >
                <ItemsControl.Items>
                    <system:String>123</system:String>
                    <system:String>123</system:String>
                    <system:String>123</system:String>
                    <system:String>123</system:String>
                    <system:String>12eee3</system:String>
                    <system:String>123eee</system:String>
                    <system:String>123fefef</system:String>
                    <system:String>123</system:String>
                    <system:String>123</system:String>
                    <system:String>123</system:String>
                    <system:String>123</system:String>
                    <system:String>12eee3</system:String>
                    <system:String>123eee</system:String>
                    <system:String>123fefef</system:String>
                </ItemsControl.Items>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
        <TextBox Grid.Column="1" TextWrapping="NoWrap" Margin="0,0,0,0"  VerticalAlignment="Center" PreviewKeyDown="txtAuto_PreviewKeyDown" MinWidth="50" />

【讨论】:

  • 这样,只需固定网格第一列的宽度,以便您的项目换行并相应地修改其他宽度以满足您的要求。
  • 这不符合要求。查看我的更新。
  • 我现在明白了这个问题。试图想出一些东西,我会尽快发布。好问题:)
猜你喜欢
  • 2011-10-24
  • 2019-12-06
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
  • 2016-03-02
相关资源
最近更新 更多