【问题标题】:Let one row in grid determine grid width, other rows draws outside clipbounds让网格中的一行确定网格宽度,其他行在剪辑边界之外绘制
【发布时间】:2013-03-18 17:25:42
【问题描述】:

我有一个在画布上具有固定位置的网格。网格的边框包含大小可能不同的图像。

现在我在图像下方添加一个 TextBlock,其中包含长度可能不同的文本。要求是无论文本的长度如何,图标都不应在画布上移动。

<Canvas>
  <Grid Canvas.Left="50" Canvas.Top="100">  
     <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
     </Grid.RowDefinitions>

     <Border BorderBrush="Black" BorderThickness="1" Background="Gray" 
             Width="{Binding RelativeSource={RelativeSource Self}, Path=Height}"
             HorizontalAlignment="Center">
         <Image Source="{Binding TheIcon}" 
                Width="{Binding IconSize}" Height="{Binding IconSize}" 
                Margin="5" />
     </Border>

     <TextBlock Grid.Row="1"
                Text="A text that is wider than the icon" 
                TextAlignment="Center"/>
   </Grid>
</Canvas>

问题是当文本变得比图标宽时,网格的宽度会增加并且图标开始向右滑动。这可以通过在边框上设置 Horizo​​ntalAlignment="Left" 来解决,但我们希望文本在图标下方居中,因为它看起来更好。

我搞砸了 ClipToBounds="False" 和不同的构建对象的方法,但我没有找到任何可行的方法。有人有一些 xaml-magic 可以分享吗?

澄清

图例
无文本 - 原始状态
不想要的状态 - 这就是我在网格中添加一行时的样子。图像从指定坐标水平移动
所需状态 - 我想保持图标在原位,同时将其下方的文本居中

【问题讨论】:

  • &lt;TextBlock Width="{Binding IconSize}" ??
  • 好的,这使得文本块和图标一样宽,这很好。缺点是它还会截断文本。
  • 尝试包装文本TextWrapping="Wrap"
  • 这样我就可以将任务标记为已完成。但用户不会高兴,因为带有
  • 然后也许设置一个最小尺寸也MinWidth="200" 或者任何值适合你的用户界面

标签: wpf xaml grid


【解决方案1】:

您可以使用转换器强制此行为在 TextBlock 上设置 -ve 左边距并在图像上设置左对齐。

类似的东西:

<Window.Resources>
  <local:MarginConverter x:Key="MarginConverter" />
</Window.Resources>
<Canvas>
  <Grid Canvas.Left="50"
        Canvas.Top="100">
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition />
    </Grid.RowDefinitions>
    <Border x:Name="image"
            Width="{Binding RelativeSource={RelativeSource Self},
                            Path=Height}"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Background="Gray"
            BorderBrush="Black"
            BorderThickness="1">
      <Image Width="{Binding IconSize}"
              Height="{Binding IconSize}"
              Margin="5"
              Source="{Binding TheIcon}" />
    </Border>
    <TextBlock Grid.Row="1"
                Text="Wider than icon Text">
      <TextBlock.Margin>
        <MultiBinding Converter="{StaticResource MarginConverter}"
                      Mode="OneWay">
          <Binding Path="ActualWidth"
                    RelativeSource="{RelativeSource Self}" />
          <Binding ElementName="image"
                    Path="ActualWidth" />
        </MultiBinding>
      </TextBlock.Margin>
    </TextBlock>
  </Grid>
</Canvas>

MarginConverter.cs

public class MarginConverter : IMultiValueConverter {
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
    double textWidth;
    Double.TryParse(values[0].ToString(), out textWidth);
    double imageWidth;
    Double.TryParse(values[1].ToString(), out imageWidth);
    if (Equals(textWidth, 0.0) || Equals(imageWidth, 0.0))
      return new Thickness();
    return new Thickness {Left = imageWidth / 2 - textWidth / 2};
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
    throw new NotImplementedException();
  }
}

可以生成这个(我只是将图像元素设置为不同的大小,因为我没有任何方便的图像。图像将从 50,50 开始。用 snoop 检查):

【讨论】:

    猜你喜欢
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2015-01-15
    相关资源
    最近更新 更多