可以使用FormattedText.MinWidth设置TextBox的宽度吗?

时间:2014-02-03 14:42:24

标签: wpf textbox word-wrap

绞尽脑汁试图解决这个问题。目标是在给定位置创建包装TextBox,其中宽度设置为文本字符串中最大单词的宽度。 FormattedText.MinWidth计算字符串中最大单词的宽度。但是将MinWidth传递给TextBox会导致TextBox略微过窄。 TextBlock没有这个问题。

显然,TextBox内部发生了一些导致此行为的事情。我不能只在TextBox宽度上添加一个固定的幻数,因为纠正问题所需的宽度增加总是会根据包裹到下一行的字符的像素宽度而有所不同。像素数将始终根据字符,字体和字体大小而有所不同。

如果有人有更多声望,请将FormattedText和MinWidth添加为标签吗?限制不会让我,这是一个愚蠢的第一个帖子newbe,这样做。我还想添加一个图像,这将使这个太容易理解,但愚蠢的限制(我说是吗?)阻止我这样做。

namespace FormattedTextExample
{
    public partial class FormattedText1 : Window
    {
        string noteText =
                "We hold these truths to be self-evident, that all men are created equal, that they " +
                "are endowed by their Creator with certain unalienable Rights, that among these are " +
                "Life, Liberty and the pursuit of Happiness.--That to secure these rights, Governments " +
                "are instituted..";

        public FormattedText1()
        {
            InitializeComponent();
            myText.Text = noteText;
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            FormattedText ft = new FormattedText(
                textToFormat: noteText,
                culture: CultureInfo.GetCultureInfo("en-us"),
                flowDirection: myText.FlowDirection,
                typeface: new Typeface(myText.FontFamily.ToString()),
                emSize: myText.FontSize,
                foreground: myText.Foreground);
            ft.MaxTextWidth = ft.MinWidth;

            DrawingContext dc = drawDest.Open();
            dc.DrawText(ft, new Point(0, 0));
            dc.Close();
            myDrawingBrush.Drawing = drawDest;

            myText.Width = ft.MinWidth;
        }
    }
}

<Window x:Class="FormattedTextExample.FormattedText1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FormattedText" Height="500" Width="500">
    <DockPanel>
        <Grid DockPanel.Dock="Top"  ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Rectangle Grid.Column="0">
                <Rectangle.Fill>
                    <DrawingBrush x:Name="myDrawingBrush" Stretch="None" 
                         AlignmentY="Top" AlignmentX="Left" >
                        <DrawingBrush.Drawing>
                            <DrawingGroup x:Name="drawDest" />
                        </DrawingBrush.Drawing>
                    </DrawingBrush>
                </Rectangle.Fill>
            </Rectangle>
            <StackPanel Grid.Column="1">
                <TextBox x:Name="myText" TextWrapping="Wrap" />
                <!-- Everything works fine if using TextBlock -->
                <!--<TextBlock x:Name="myText" TextWrapping="Wrap" />-->
            </StackPanel>
        </Grid>
    </DockPanel>
</Window>

1 个答案:

答案 0 :(得分:1)

文本框需要更多空间的原因是其控件模板的定义方式。

这是默认控件模板的外观(来自MSDN):

    <ControlTemplate TargetType="{x:Type TextBoxBase}">
        <Border Name="Border"
                BorderThickness="1"
                CornerRadius="2"
                Padding="2">
            <Border.Background>
                <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
            </Border.Background>
            <Border.BorderBrush>
                <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
            </Border.BorderBrush>
            <!-- VisualStateManager code -->
            <ScrollViewer x:Name="PART_ContentHost" Margin="0" />
        </Border>
    </ControlTemplate>

研究默认控件模板或定义自己的模板有助于确定需要为文本框分配多少额外空间。