There is a form that can take any size. On this form there are 7 TextBlock with text of different lengths. It is necessary for TextBlock stretch across the entire width of the form observing the following parameters:

  • If the TextBlock 1 character, then it must be a square.
  • All TextBlock should have the same height and the same font size.

Grid did not fit, because I need the same distance between the TextBlock . I also tried UniformGrid but it just stretches the elements, making them different in height. I tried the Viewbox , but I did not manage to achieve the desired results.

How can you achieve the desired result with the layout? I have a variant with an event for resizing a form to manually resize a TextBlock , but it seems to me a crutch. WPF is quite difficult for me to understand, so I decided to ask.

Form Code:

 <Window x:Class="Test.Test" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Test" mc:Ignorable="d" Height="150" Width="500" WindowStyle="None" FontFamily="Arial" FontSize="14" ResizeMode="CanResizeWithGrip"> <StackPanel Orientation="Horizontal" Margin="5,0"> <Border Background="#FF323232" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center" MinWidth="30" MinHeight="30"> <TextBlock Text="Rafd Hiljo" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> <Border Background="#FF323232" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" MinWidth="30" MinHeight="30"> <TextBlock Text="MD" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> <Border Background="#FF323232" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" MinWidth="30" MinHeight="30"> <TextBlock Text="T" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> <Border Background="#FF323232" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" MinWidth="30" MinHeight="30"> <TextBlock Text="Lader" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> <Border Background="#FF323232" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" MinWidth="30" MinHeight="30"> <TextBlock Text="W" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> <Border Background="#FF323232" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" MinWidth="30" MinHeight="30"> <TextBlock Text="Q" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> <Border Background="#FF323232" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" MinWidth="30" MinHeight="30"> <TextBlock Text="PAT" Foreground="#FFFFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="7" /> </Border> </StackPanel> </Window> 

The form:

original design elements

What I would like to achieve (arrows with the same color are equal):

desired design elements

  • But the text of the elements themselves is known at the time of launching the program? - Vadim Ovchinnikov
  • @VadimOvchinnikov; It changes during work. The main text is from 1 to 10 characters long. - Jagailo pm
  • And the text elements themselves, and not their contents, are also created during the program launch or not? - Vadim Ovchinnikov
  • @VadimOvchinnikov, no items themselves will be on the form. - Jagailo
  • Font take monosigned - Andrew NOP

1 answer 1

First of all, I highly recommend storing all duplicate property values ​​in resource styles, which is reflected in the decision code.

To solve this problem using the Grid . In elements where the text is one character, you must use the width of the corresponding column Auto , in other cases - * .

Also, for Border , remove HorizontalAlignment="Center" so that the element stretches normally (so that the default value of HorizontalAlignment="Stretch" remains).

Result:

 <Grid> <Grid.Resources> <Style TargetType="Border"> <Setter Property="Background" Value="#323232" /> <Setter Property="Margin" Value="5" /> <Setter Property="MinWidth" Value="30" /> <Setter Property="MinHeight" Value="30" /> <Setter Property="VerticalAlignment" Value="Center" /> </Style> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="#fff" /> <Setter Property="Padding" Value="7" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" /> </Style> </Grid.Resources> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Border> <TextBlock Text="Rafd Hiljo" /> </Border> <Border Grid.Column="1"> <TextBlock Text="MD" /> </Border> <Border Grid.Column="2"> <TextBlock Text="T" /> </Border> <Border Grid.Column="3"> <TextBlock Text="Lader" /> </Border> <Border Grid.Column="4"> <TextBlock Text="W" /> </Border> <Border Grid.Column="5"> <TextBlock Text="Q" /> </Border> <Border Grid.Column="6"> <TextBlock Text="PAT" /> </Border> </Grid> 

Dynamically changeable text

In order to be able to dynamically change the contents of the text and change the size of the column, use Binding and the spellings of our Converter:

 public class TextToColumnWidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => new GridLength(1, ((string)value).Length == 1 ? GridUnitType.Auto : GridUnitType.Star); public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); } 

XAML code:

 <Grid> <Grid.Resources> <Style TargetType="Border"> <Setter Property="Background" Value="#323232" /> <Setter Property="Margin" Value="5" /> <Setter Property="MinWidth" Value="30" /> <Setter Property="MinHeight" Value="30" /> <Setter Property="VerticalAlignment" Value="Center" /> </Style> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="#fff" /> <Setter Property="Padding" Value="7" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" /> </Style> <local:TextToColumnWidthConverter x:Key="TextToColumnWidthConverter" /> </Grid.Resources> <Grid.ColumnDefinitions> <ColumnDefinition Width="{Binding ElementName=t1, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> <ColumnDefinition Width="{Binding ElementName=t2, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> <ColumnDefinition Width="{Binding ElementName=t3, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> <ColumnDefinition Width="{Binding ElementName=t4, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> <ColumnDefinition Width="{Binding ElementName=t5, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> <ColumnDefinition Width="{Binding ElementName=t6, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> <ColumnDefinition Width="{Binding ElementName=t7, Path=Text, Converter={StaticResource TextToColumnWidthConverter}}" /> </Grid.ColumnDefinitions> <Border> <TextBlock Name="t1" Text="Rafd Hiljo" /> </Border> <Border Grid.Column="1"> <TextBlock Name="t2" Text="MD" /> </Border> <Border Grid.Column="2"> <TextBlock Name="t3" Text="T" /> </Border> <Border Grid.Column="3"> <TextBlock Name="t4" Text="Lader" /> </Border> <Border Grid.Column="4"> <TextBlock Name="t5" Text="W" /> </Border> <Border Grid.Column="5"> <TextBlock Name="t6" Text="Q" /> </Border> <Border Grid.Column="6"> <TextBlock Name="t7" Text="PAT" /> </Border> </Grid> 
  • But if all TextBlock is 1 character long. They will not be stretched, but will remain 30x30. - Jagailo
  • @Jagailo Did not understand the last comment. Well, yes, they will not stretch if everyone is 1 character long, that's right. And what do you want to say? - Vadim Ovchinnikov
  • In the question I wrote that the height was the same, but the elements should be scaled and not only in width. That is, if there is a place in height and width, then the squares (with one symbol) should stretch across the entire width. Perhaps this is only code done - Jagailo
  • @Jagailo It is necessary to stretch in height only if all elements are squares, right? That is, in other cases, the application works correctly? - Vadim Ovchinnikov