如何使WPF中的TextBlock只能增大而不能缩小?

3
在我的应用程序中,我多次设置名为tbkStatus的TextBlock的文本。如何使TextBlock只增长以适应文本而不在文本更改时缩小?StatusText每隔几秒钟更改一次,有长文本和短文本的状态。我希望我的TextBlock能够自适应最长文本的大小,即使存在短文本,TextBlock也不应该缩小。
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="200" Width="400" 
        WindowStartupLocation="CenterScreen" 
        ResizeMode="CanMinimize" Topmost="True">
    <Window.Resources>

    </Window.Resources>
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="AUTO" />
            <RowDefinition Height="AUTO" />
            <RowDefinition Height="AUTO" />
            <RowDefinition Height="AUTO" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Text="Please wait ..." Grid.Row="1" Margin="6"/>

        <TextBlock Name="tbkStatus" Grid.Row="2" Margin="6" TextWrapping="Wrap" Text="{Binding StatusText}"/>

        <ProgressBar Grid.Row="3" Margin="6" Height="20"/>
        <Button Grid.Row="4" HorizontalAlignment="Center" Padding="24,3" Margin="6" Content="Stop"/>
    </Grid>
</Window>

展示 TextBlock 的 XAML 标记,以及包围它的容器。 - Alex
我无法真正地复现这个问题。你期望的确切行为是什么? - Alex
将最小宽度属性设置为所需的值,以避免收缩。 - Daniele Sartori
3个回答

3

Xaml 单独解决方案:

<TextBlock Text="{Binding StatusText}"
           MinWidth="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth}"
           HorizontalAlignment="Left"/>

无论何时 Width 增加,MinWidth 也会增加。因此,控件无法收缩回去。

0

我猜你可以监听布局事件,例如SizeChangedLayoutUpdated,或编写某种行为。

在下面的示例中,基本前提是监听这些事件之一,并强制控件永远不会缩小。

注意:这完全没有经过测试,只是一个想法,也许你可以设置MinWidth属性。

Xaml

<TextBlock x:Name="tbkStatus" SizeChanged="OnSizeChanged"/>

代码后台

private double _lastSize;

private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
    var textBlock = sender as TextBlock;
    if (textBlock == null)
    {
        return;
    }

    if (e.WidthChanged)
    {
        if (textBlock.Width < _lastSize)
        {
            textBlock.Width = _lastSize;
        }
        _lastSize = textBlock.Width;
    }
}

注意

SizeChangedEventArgs 类有许多属性,您可能可以利用它们。


我猜它只会在第一次起作用,但是在你明确设置宽度之后,你将不会再次收到OnSizeChanged事件。 - google dev
@GoogleFan 是的,这就是为什么我在想像 MinWidth 这样的东西。 - TheGeneral
如果文本比更新前更长,则在TextChanged事件中使用它来更新 Width,否则不执行任何操作。 - Lion King
@LionKing 是的,那也是公平的。 - TheGeneral
请写下一个经过尝试并且有效的答案,非常感谢。 - google dev

-1
你可以像这样做:
 <TextBlock Name="tbkStatus" Grid.Row="2" Margin="6" TextWrapping="Wrap" Text="{Binding StatusText}"/>

由于没有事件,因此这将完成该工作

DependencyPropertyDescriptor dp = DependencyPropertyDescriptor.FromProperty(TextBlock.TextProperty, typeof(TextBlock));
int textLength =0 


dp.AddValueChanged(tbkStatus, (object a, EventArgs b) =>
{
      if (textLength < tbkStatus.Text.Length)
      {
       textLength = tkbStatus.Text.Length;
       tbkStatus.Width = textLength * SomeValue; //You have to play around and see what value suits you best since it depends on font and it's size
      }

});

或者,您可以使用一个 TextBox 并将其设置为只读,然后使用 TextChanged 事件。


1
不太适合我,我在我的问题中添加了解释。谢谢。 - google dev
我更新了答案,你可以结合@Saruman提供的答案和我的贡献,得到一个适合你问题的好解决方案。 - Lion King
请问您能否编写一个已经测试并且可用的示例代码? - google dev
@Google粉丝,看一下,我认为这应该可以工作。由于我现在没有Visual Studio,所以我没有检查它。 - Lion King

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接