在扩展宽度之前使 TextBlock 使用所有可用高度

Make a TextBlock use all available height before expand the width

我有一个“hero/vertical”按钮(里面有一个图像)由此 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>

用法:

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

MaxSize控制控件内图片的最大尺寸

示例图片:

预期图像:

我的问题:

我所有的垂直按钮的 MaxWidth 都是 60,English 没问题,问题出在其他语言上,当 60px 太小时,按钮应该横向变大,但仍然使用所有的高度。

那么,如何让 TextBlock 在扩展宽度之前使用所有可用的高度?

TextWrapping 仅在没有可用宽度时才起作用,例如当我将宽度设置为 60 时。

有趣的问题。如果不知道最宽字的宽度,您将不知道如何定义 TextBox 的宽度来获得您想要的自动换行。要全力以赴,您可以使用某种语言 API 并使用它的分词器。对于我认为您的代码中的一个孤立案例,也许您可​​以自己执行此操作并让 TextBox 自动调整自身大小、居中并实现您想要的结果。

编写一个转换器来强制单词之间的中断。我把它放在一起来演示这项技术......当然,你会想要适当地适应你的解决方案。

代码

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>

结果