1

キャンバス上の固定位置を持つグリッドがあります。グリッドには、サイズが異なる可能性がある画像を含む境界線があります。

ここで、長さが異なる可能性のあるテキストを含む 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 を持っている人はいますか?

明確化

ここに画像の説明を入力

凡例
テキストなし- 元の状態
望ましくない状態- グリッドに行を追加すると、このようになります。指定した座標から画像を水平方向にずらした
状態 望ましい状態- アイコンをその下のテキストを中央に配置したまま、その位置に保持したい

4

1 に答える 1

1

コンバーターを使用してこの動作を強制し、TextBlock に -ve Left マージンを設定し、画像に Left Alignment を設定できます。

何かのようなもの:

<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 から始まります。スヌープで確認しました):

拡大画像

小さい画像

于 2013-03-28T22:32:30.663 に答える