简体   繁体   中英

Make a TextBlock use all available height before expand the width

I have a "hero/vertical" button (with an image inside) defined by this Style :

<ControlTemplate TargetType="{x:Type controls:ImageButton}">
    <Grid MinHeight="{TemplateBinding MinHeight}" Background="{TemplateBinding Background}" Width="Auto" SnapsToDevicePixels="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <!-- Image -->
        <Viewbox x:Name="ViewBoxInternal" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" IsEnabled="{TemplateBinding IsEnabled}"
                 Stretch="Uniform" StretchDirection="Both" Effect="{x:Null}"
                 Width="{TemplateBinding MaxSize}" Height="{TemplateBinding MaxSize}" 
                 MaxHeight="{TemplateBinding MaxSize}" MaxWidth="{TemplateBinding MaxSize}">
            <ContentPresenter ContentSource="{TemplateBinding Content}" Width="Auto" Height="Auto" 
                              HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Viewbox>

        <!-- Text -->
        <TextBlock x:Name="TextBlockInternal" Grid.Row="1"
                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="3,2,3,3"
                   VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Text="{TemplateBinding Text}" 
                   TextWrapping="Wrap" Effect="{TemplateBinding Effect}" TextAlignment="Center"/>
    </Grid>
</ControlTemplate>

Usage:

<controls:ImageButton Text="Webcam Recording" Content="{StaticResource Vector.Camera.New}" 
          Margin="0" Height="70" MaxSize="30">

MaxSize controls the maximum size of the image inside the control.

Example image:

图 1

Expected image:

预期图像

My Problem:

All of my vertical buttons have a MaxWidth of 60, that's okay for English , the problem starts with other languages, when 60px is too small, so the button should grow bigger sideways, but still use all of the height.

So, How can I make the TextBlock use all available height before expanding the width?

TextWrapping only works when there's no width available, like when I set the Width to 60.

Interesting question. Without knowing the width of the widest word, you will not know how to define the width of the TextBox to get the automatic wrapping you want. To go all out on this, you could make use of some Language API and use its wordbreakers. For what I believe is an isolated case in your code, perhaps you can do this yourself and let the TextBox auto-size itself, centered, and achieve the result you want.

Write a Converter to force breaks between words. I threw this together to demonstrate the technique...you will want to adapt is appropriately to your solution of course.

Code

public partial class MainWindow : Window
{
    public string LongText
    {
        get { return (string)GetValue(LongTextProperty); }
        set { SetValue(LongTextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for LongText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty LongTextProperty =
        DependencyProperty.Register("LongText", typeof(string), typeof(MainWindow), new PropertyMetadata(string.Empty));


    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        LongText = "Some Really Long Text";
    }
}

public class WordBreakConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var text = (string)value;
        text = text.Replace(" ", Environment.NewLine);
        return text;
    }

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

XAML

<Window.Resources>
    <local:WordBreakConverter x:Key="WordBreakConverter"/>
</Window.Resources>

<Grid x:Name="LayoutRoot">
    <StackPanel>
        <TextBlock Text="WPF" FontSize="36" Margin="20" Foreground="Orange" HorizontalAlignment="Center"/>
        <TextBlock Text="{Binding LongText, Converter={StaticResource WordBreakConverter}}" TextAlignment="Center"/>
    </StackPanel>
</Grid>

Result

分词符文本示例

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM