首页 \ 问答 \ 防止包装TextBlock影响布局(Prevent wrapping TextBlock from affecting layout)

防止包装TextBlock影响布局(Prevent wrapping TextBlock from affecting layout)

我已经遇到过这个问题几次,还没有找到一个简单的解决方案。 当TextBlock (带有TextWrapping="Wrap" )嵌入到另一个未指定其宽度的元素中时, TextBlock会扩展为其父级允许的大小,而不是首先尝试包装其文本。 例如,我目前正在研究TextBlock ValidationTemplate 。 以下是模板当前处理文本的时间长于TextBox的宽度:

当前验证模板

这显然不是最佳的。 以下是我希望它出现的方式:

期望的验证模板

这是生成第一个布局的ControlTemplate的XAML:

<ControlTemplate>
  <DockPanel LastChildFill="True">
    <Border DockPanel.Dock="Top" BorderBrush="Red" BorderThickness="1">
      <DockPanel>
        <AdornedElementPlaceholder x:Name="TargetTextBox" />
        <Grid x:Name="WarningBoxContainer" Background="Red" Width="{Binding ElementName=TargetTextBox, Path=ActualHeight}" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}">
            <Path Margin="5" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
        </Grid>
      </DockPanel>
    </Border>
    <Border DockPanel.Dock="Top" Margin="0,2,0,0">
      <TextBlock Text="Something very terrible has happened" TextWrapping="Wrap"/>
    </Border>
  </DockPanel>
</ControlTemplate>

有没有人知道在尝试扩展之前如何制作TextBlock包装?


I've run into this issue a few times and have yet to find a simple solution. When a TextBlock (with TextWrapping="Wrap") is embedded inside another element that doesn't specify its width, the TextBlock expands as large as its parent allows instead of first trying to wrap its text. For example, I'm currently working on a TextBlock ValidationTemplate. Here's how the template currently handles text longer than the width of the TextBox:

Current validation template

which is obviously not optimal. Here's how I'd like it to appear:

Desired validation template

Here's the XAML for the ControlTemplate that's producing the first layout:

<ControlTemplate>
  <DockPanel LastChildFill="True">
    <Border DockPanel.Dock="Top" BorderBrush="Red" BorderThickness="1">
      <DockPanel>
        <AdornedElementPlaceholder x:Name="TargetTextBox" />
        <Grid x:Name="WarningBoxContainer" Background="Red" Width="{Binding ElementName=TargetTextBox, Path=ActualHeight}" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}">
            <Path Margin="5" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
        </Grid>
      </DockPanel>
    </Border>
    <Border DockPanel.Dock="Top" Margin="0,2,0,0">
      <TextBlock Text="Something very terrible has happened" TextWrapping="Wrap"/>
    </Border>
  </DockPanel>
</ControlTemplate>

Does anyone know how to make a TextBlock wrap before trying to expand?


原文:https://stackoverflow.com/questions/19337298
更新时间:2021-06-06 21:06

最满意答案

当然,我发布后几分钟,我找到了答案。

我想到了使用绑定从这篇文章强制执行TextBlock的宽度。

在我的例子中,将TextBlock的宽度绑定到AdornedElementPlaceholder元素的ActualWidth上:

<ControlTemplate>
  <DockPanel LastChildFill="True">
    <Border DockPanel.Dock="Top" BorderBrush="Red" BorderThickness="1">
      <DockPanel>
        <AdornedElementPlaceholder x:Name="TargetTextBox" />
        <Grid x:Name="WarningBoxContainer" Background="Red" Width="{Binding ElementName=TargetTextBox, Path=ActualHeight}" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}">
            <Path Margin="5" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
        </Grid>
      </DockPanel>
    </Border>
    <Border DockPanel.Dock="Top" Margin="0,2,0,0">
      <TextBlock Text="Something very terrible has happened" TextWrapping="Wrap" HorizontalAlignment="Left" Width="{Binding ElementName=TargetTextBox, Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}"/>
    </Border>
  </DockPanel>
</ControlTemplate>

最终产品:

在此处输入图像描述


Of course, minutes after I post, I find the answer.

I got the idea of using a binding to enforce the width of the TextBlock from this post.

In my case, binding the TextBlock's width to the ActualWidth of the AdornedElementPlaceholder element did it:

<ControlTemplate>
  <DockPanel LastChildFill="True">
    <Border DockPanel.Dock="Top" BorderBrush="Red" BorderThickness="1">
      <DockPanel>
        <AdornedElementPlaceholder x:Name="TargetTextBox" />
        <Grid x:Name="WarningBoxContainer" Background="Red" Width="{Binding ElementName=TargetTextBox, Path=ActualHeight}" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}">
            <Path Margin="5" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
        </Grid>
      </DockPanel>
    </Border>
    <Border DockPanel.Dock="Top" Margin="0,2,0,0">
      <TextBlock Text="Something very terrible has happened" TextWrapping="Wrap" HorizontalAlignment="Left" Width="{Binding ElementName=TargetTextBox, Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}"/>
    </Border>
  </DockPanel>
</ControlTemplate>

The end product:

enter image description here

相关问答

更多

如何在WPF TextBlock中强制文本换行(How can I force a text wrapping in a WPF TextBlock)

如果你使用LineBreak,它应该做你想要的。 <TextBlock> Hello<LineBreak/>World </TextBlock> 你也可以使用: <TextBlock Text="Hello&#x0a;World" /> If you use LineBreak, it should do what you want. <TextBlock> Hello<LineBreak/>World </TextBlock> You could also use : <T ...

防止包装TextBlock影响布局(Prevent wrapping TextBlock from affecting layout)

当然,我发布后几分钟,我找到了答案。 我想到了使用绑定从这篇文章强制执行TextBlock的宽度。 在我的例子中,将TextBlock的宽度绑定到AdornedElementPlaceholder元素的ActualWidth上: <ControlTemplate> <DockPanel LastChildFill="True"> <Border DockPanel.Dock="Top" BorderBrush="Red" BorderThickness="1"> <Dock ...

TextBlock TextWrapping不包装#2(TextBlock TextWrapping not wrapping #2)

那么你的TextBlock不需要打包,因为你的指定Width为Auto因为它的ColumnDefinition允许它获取所需的所有Width ,即使以溢出为代价。 您需要将列的宽度设置为“*”,以允许TextWrapping在请求的宽度超出允许范围时启动,或者使用Binding类似的方式手动强制MaxWidth <TextBlock Name="tbText" Grid.Row="1" MaxWidth="{Binding RelativeSource={RelativeSource FindAn ...

wpf textblock autosize / layout stackpanel(wpf textblock autosize/layout in stackpanel)

创建一个实现IMultiValueConverter的转换器,然后在文本上使用MultiBinding,以便每行只有一个TextBlock,如下所示: class MultiStringConverter : IMultiValueConverter { public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture ) ...

ScrollViewer和TextBlock包装(ScrollViewer and TextBlock wrapping)

只需给TextBlock一个MaxWidth ,它就是GroupBox的ActualWidth ,或者甚至是layoutGrid (因为你的GroupBox具有相同的宽度)。 这会强制TextBlock在Width超过该维度时必须换行,从而满足您的要求。 所以类似于: <GroupBox x:Name="grpBox" Grid.Row="2" Grid.ColumnSpan="3"> <TextBlock MaxWidth="{Binding Elem ...

TextBlock在WPF布局中包装(TextBlock Wrapping in WPF Layout)

将水平stackpanel更改为dockpanel或grid(我会使用dockpanel)。 这可以通过此线程中接受的答案来解释 - 对接板和网格的包装在两个方向上受到约束 ,而不是在其定向方向上包含内容的堆叠面板。 Change the horizontal stackpanel to a dockpanel or grid (I would use a dockpanel). This is explained by the accepted answer in this thread - w ...

Listbox中的Silverlight文本块使其扩展而不是包装文本(Silverlight Textblock inside Listbox causes it to expand instead of wrapping the text)

尝试将ScrollViewer.HorizontalScrollBarVisibility="Disabled"添加到ListBox。 Try to add ScrollViewer.HorizontalScrollBarVisibility="Disabled" to your ListBox.

用于包装的TextBlock的动态字体大小(Dynamic Fontsize for TextBlock with wrapping)

我的解决方案如下: 将fontsize设置为一个值,您不希望任何更大的值。 当您更改字体大小或更改内容时,TextBlock的ActualHeight会发生变化。 我基于此建立了解决方案。 您应该为SizeChanged事件创建一个事件处理程序并将以下代码写入它。 private void MyTextBlock_SizeChanged(object sender, SizeChangedEventArgs e) { double desiredHeight = 80; // Here y ...

TextBlock不包装Silverlight应用程序(TextBlock not Wrapping Silverlight application)

问题是父视图应用的样式,特别是Telerik对象。 解决方案是找到该样式,对其进行反编译并将其复制到我们的某个文件中,并将scrollviewer更改为边框。 The issue was a style that was being applied by the parent view and specifically a Telerik object. The solution was to find that style, decompile it and copy is to one of ...

WPF - 我可以阻止包装TextBlock中的短语的自动换行吗?(WPF - can I prevent word-wrap on a phrase within a wrapping TextBlock?)

回想起来,解决方案似乎很明显: 只需将我的非单词包装部分放入嵌套的“TextBlock”中,并禁用自动换行。 The solution seems obvious in retrospect: Simply put my non-word-wrapped part in a nested 'TextBlock' with word-wrap disabled.

相关文章

更多

最新问答

更多
  • 如何从远程文件拉取文件而不覆盖本地文件?(How do I pull files from remote without overwriting local files?)
  • Reactjs:状态改变时重新渲染iframe(Reactjs: re-renders iframes when state changed)
  • 奇怪的网址,以及跟随php页面流程的困难(odd url, and difficulty in following the php page flow)
  • 标签活动无效(Tab Activity is not working)
  • JavaME合适的语法编译器建议?(JavaME-suitable grammar compiler recommendations?)
  • 指定参数(Specifying arguments)
  • 可以通过Ruby插件或控制台覆盖Sketchup中的键盘快捷键吗?(Can one override keyboard shortcuts in Sketchup through the a Ruby Plugin or Console?)
  • 计算Java EE Web App中用户数的最佳方法(Best way to count number of users in a Java EE web App)
  • 无法使用templateUrl加载cordova中的外部模板(unable to load external templates in cordova with templateUrl)
  • PHPExcel:写入期间无法使用缓存(PHPExcel: Unable to use cache during write)
  • 在javascript中嵌套这个指针(nested this pointer in javascript)
  • 谁跟领航致远培训过,有问题问下啊
  • 控制器要求在入门时下载(Controller ask to download on entry)
  • 未能通过conda安装Asyncio(Failure to install Asyncio via conda)
  • 如何查找已完成项目的总长度?(How to find length of total completed items?)
  • 如何检查OleInitialize是否已被调用?(How to check if OleInitialize has already been called?)
  • SQL在特定范围内返回列中具有最大值的行(SQL Returning rows with max value in column, within a specific range)
  • preg_match从url获取id(preg_match get the id from url)
  • 如何在运算符中为make方程转换perl变量?(How to convert a perl variable in a operator for make equations?)
  • 在导航上方添加空格/标题。(Add a white space/ header above navigation.)
  • MeetingItem已保存;(MeetingItem saved; but change now shown in Calendar)
  • c#vb:我们应该使用System.Lazy进行资源密集型任务吗?(c# vb: Should we use System.Lazy for resource-intensive task? (when threading is not needed))
  • 为什么在armeabi代码中使用armeabi-v7a代码?(Why use armeabi-v7a code over armeabi code?)
  • 获取请求的自定义标头(Java HTTP)(Fetching a custom header of a request (Java HTTP))
  • 是否可以在嵌套的if语句中从varchar转换为numeric以动态评估参数?(Is it possible to convert from varchar to numeric within a nested if statement in order to dynamically evaluate a parameter?)
  • 如何将Html.ActionLink转换为链接到Ajax调用的按钮?(How to convert from Html.ActionLink to a button linked to Ajax call?)
  • 应用程序如何处理Windows符号链接?(How are Windows symbolic links treated by the apps?)
  • html,js,css在jsfiddle中工作,但不在sharepoint中(html, js, css works in jsfiddle but not in sharepoint)
  • 从Ruby脚本调用Elasticsearch Rest API(Calling Elasticsearch Rest API from Ruby script)
  • 如何将嵌套setTimeouts转换为承诺(How to convert nested setTimeouts to promises)