用于自动调整文本块的WPF布局和右侧浮动的图标 - 如何?

时间:2010-07-12 20:56:01

标签: wpf xaml layout grid

我正在尝试获得一个图标浮动在文本块右端的布局;文本块增长/缩小为内容。如果没有在网格外运行的文本块,我无法实现这一点。例如:

<Grid x:Name="LayoutRoot" Width="500" HorizontalAlignment="Left" ShowGridLines="True" >
 <Grid.ColumnDefinitions>
  <ColumnDefinition Width="Auto" />
  <ColumnDefinition Width="40"/>
 </Grid.ColumnDefinitions>
   <TextBlock x:Name="textBlock" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="0" >
  <TextBlock.Text>longer keeps going and going testgrand you going and then t 
</TextBlock.Text>
  </TextBlock>
<Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="1"/>
</Grid>

看起来像自然方法,并且当文本比列/网格短时工作正常,除了文本框和列将无限增长而不遵守网格的边界。

与左侧图标相反,使用更简单的布局工作正常,文本块不会无限增长。这是通过这个标记来实现的:

<Grid Grid.Row="1" Width="500" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
  <ColumnDefinition Width="40" />
  <ColumnDefinition />
  </Grid.ColumnDefinitions>
  <Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41"  Width="41" Grid.Column="0"/>
  <TextBlock x:Name="textBlock2" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="1" HorizontalAlignment="Left">
  <TextBlock.Text>longer testgrow the textblock and it will just keep growing but it will stop when it gets too </TextBlock.Text>
 </TextBlock>
</Grid>

任何帮助表示赞赏。如果网格不起作用,是否有一个替代布局,我可以在文本右侧浮动图标,文本块会在文本太长时修剪文本?

此外:

  • 不,使用* size列不起作用,因为列是固定的,图标不会浮动在文本末尾

  • DockPanel也不起作用,或者至少我或其他我认为无法使用的人。它能做的最好的事情就是在停靠栏右侧外面留下半截图标。

4 个答案:

答案 0 :(得分:2)

通过在TextBlock上设置MaxWidth,您能获得所需内容吗?如果您在第一个示例中添加MaxWidth="460"

<Grid x:Name="LayoutRoot" Width="500" HorizontalAlignment="Left" ShowGridLines="True" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="40"/>
    </Grid.ColumnDefinitions>
    <TextBlock MaxWidth="460" x:Name="textBlock" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="0" >
        <TextBlock.Text>longer keeps going and going testgrand you going and then t</TextBlock.Text>
    </TextBlock>
    <Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="1"/>
</Grid>

然后TextBlock将水平增长,并且右边的矩形总是立即生成。它不会宽于460,因此TextBlock加上Rectangle不应该大于500.如果你需要Grid动态调整大小,那么你可以使用转换器将TextBlock.MaxWidth绑定到Grid.ActualWidth减去Rectangle的宽度。


编辑:

实际上,它应该比那更简单。在列上使用星号大小调整,但在网格上设置MaxWidth而不是Width。这样,当文本较小时,网格本身会变小,因此矩形始终位于文本的边缘。

<Grid x:Name="LayoutRoot" MaxWidth="500" HorizontalAlignment="Left" ShowGridLines="True" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="40"/>
    </Grid.ColumnDefinitions>
    <TextBlock x:Name="textBlock" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="0" >
        <TextBlock.Text>longer keeps going and going testgrand you going and then t</TextBlock.Text>
    </TextBlock>
    <Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="1"/>
</Grid>

答案 1 :(得分:0)

以下代码将导致以下输出,是您要查找的内容???

持续时间更长...... [红色矩形]

<Grid Width="200">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Text="longer keeps going and going testgrand you going and then t" TextTrimming="CharacterEllipsis"/> 
    <Rectangle Grid.Column="1" Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" />
</Grid>

答案 2 :(得分:0)

有人在内部提出了这个答案,其中有效:

    <WrapPanel HorizontalAlignment="Left" VerticalAlignment="Top">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="10" />
            </Grid.ColumnDefinitions>
            <AccessText TextTrimming="CharacterEllipsis" Grid.Column="0" Margin="0,0,4,0" Text="type more typingon the long hi longer than what if you keep tyingin and get to the end and that's why it changed because you were in the middle" />
            <Border Grid.Column="1" Width="10" Height="10" Background="Red" />
        </Grid>
    </WrapPanel>

包裹乐似乎提供了必要的魔力。我没有尝试过Quartermeister,但会保存以供将来参考!

我们的最终布局更复杂,看起来像这样(它是扩展器的标题栏):

<WrapPanel Orientation="Vertical">
    <Grid x:Name="HeaderSite" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="19" />
            <ColumnDefinition Width="16" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" /> <!-- 7/14: fix from list: wrap the whole thing in a wrappanel. Allows for one * col. -->
            <ColumnDefinition Width="19" />
        </Grid.ColumnDefinitions>
        <ToggleButton  x:Name="buttonExpanderToggleButton"
            Height="20" VerticalAlignment="Top"
                />
        <Image x:Name="imageActivityIcon" Grid.Column="1"
            Height="16" Width="16" 
            HorizontalAlignment="Left" VerticalAlignment="Top" 
            Margin="0"/>

        <AccessText x:Name="textActivityID" 
            Grid.Column="2"
            VerticalAlignment="Top" Margin="5,2,0,0" 
            TextTrimming="CharacterEllipsis"
            FontSize="12" HorizontalAlignment="Left" Text="MA77777"/>
        <AccessText x:Name="textActivityHeader" 
            Grid.Column="3"
            VerticalAlignment="Top" Margin="0,2,0,0" 
            TextTrimming="CharacterEllipsis"
            FontSize="12" HorizontalAlignment="Left" Text="Title title title title aand Title title title title a little and if you type more what happens as you keep typing "/>
        <AccessText x:Name="textActivityStatus" 
            FontWeight="Normal" 
            FontStyle="Italic" 
            Grid.Column="4"
            TextTrimming="CharacterEllipsis"
            VerticalAlignment="Top" Margin="0,2,8,0"
            FontSize="12" HorizontalAlignment="Left" Text="(On Hold)"/>
        <Image x:Name="imageLink" 
            Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="5"/>
    </Grid>
</WrapPanel>

即使使用其他自动调整大小的列,这也可以正常工作。关键似乎是wrappanel和一个*大小的列。如果将它们全部设置为自动则不起作用。

我希望这个和Quartermeister的答案可以帮到某个人,因为这让我开心#$%#$%疯狂。

答案 3 :(得分:0)

我有一个类似的问题;我想显示一些具有外部尺寸的边框区域但包含两个TextBlock的内容,其中第一个是自动调整大小,第二个是固定大小,第二个浮点数随着第一个变小而停下来在右边缘(因此第一个块的文本被剪切,而不是第二个块不可见)。

提取前面的答案,似乎魔术的关键只是使用HorizontalAlignment="Left",第一列设置为星形。

<Border BorderThickness="1" BorderBrush="Black">
    <Grid HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="{Binding Value}" />
        <TextBlock Grid.Column="1" Text="&#x23EB;" Margin="4,0,0,0" Foreground="Blue" />
    </Grid>
</Border>

看来,这种工作方式是Border保持全宽(由其父级布局设置),而Grid会根据其内容调整大小- -除非宽度不会大于包含的Border。这样可使第二个TextBlock保持可见。

Example of text alignment