【发布时间】:2014-11-28 16:40:22
【问题描述】:
我需要在可调整大小的列中显示一段文本。文本应该用溢出来换行,但是对于给定的列大小,用户应该能够水平滚动以查看溢出的文本。
我不相信这可以通过开箱即用的控件来实现;如果我错了,请告诉我。我试图通过自定义控件来实现这一点:
public class Sizer : ContentPresenter
{
static Sizer()
{
ContentPresenter.ContentProperty.OverrideMetadata(typeof(Sizer), new FrameworkPropertyMetadata(ContentChanged)); ;
}
public Sizer() : base() {}
protected override Size MeasureOverride(Size constraint)
{
var childWidth = Content==null ? 0.0 : ((FrameworkElement)Content).RenderSize.Width;
var newWidth = Math.Max(RenderSize.Width, childWidth);
return base.MeasureOverride(new Size(newWidth, constraint.Height));
}
private static void ContentChanged(DependencyObject dep, DependencyPropertyChangedEventArgs args)
{
var @this = dep as Sizer;
var newV = args.NewValue as FrameworkElement;
var oldV = args.OldValue as FrameworkElement;
if (oldV != null)
oldV.SizeChanged -= @this.childSizeChanged;
if(newV!=null)
newV.SizeChanged += @this.childSizeChanged;
}
private void childSizeChanged(object sender, SizeChangedEventArgs e)
{
this.InvalidateMeasure();
}
}
...我可以像这样在一个简单的 WPF 应用程序中对其进行测试:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" VerticalAlignment="Top">
<local:Sizer>
<local:Sizer.Content>
<TextBlock Background="Coral" Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaa"
TextWrapping="WrapWithOverflow" />
</local:Sizer.Content>
</local:Sizer>
</ScrollViewer>
<GridSplitter Grid.Column="1" Background="Black" VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="5" />
</Grid>
这很有效。它正确地换行和显示文本,水平滚动条让我查看溢出的文本。如果我将列调整到右侧(更大),则文本会正确重新换行。但是,如果我将列向左(更小)调整大小,则文本不会重新换行。因此,例如,如果我将列的大小调整到右侧,以便所有文本都在一行上,那么无论后续调整大小如何,它都将保持在一行上。这是一个不可接受的错误。
我已经对这段代码进行了大量修改,尽管我还没有你所谓的寻找解决方案的好策略。我不知道也无法发现任何强制文本块重新包装其内容的机制。有什么建议吗?
【问题讨论】:
-
只有一条评论,但我已经看到了,当您减小尺寸时,UI 渲染不会重新测量。甚至从 MSFT 中发现了一些经过设计的东西。
-
这看起来很有希望。你有没有机会获得你所读到的内容的链接?
-
不,但如果你搜索我的问题,我知道我在 SO 上问过这个问题。我得到了一个很好的答案,只是告诉我这是一个死胡同。
-
我怀疑您指的是:“[VirtulizingStackPanel] 的 Measure 算法......记住有史以来发现的最大尺寸,并强制所有未来的 Measure 调用报告至少一样大的尺寸。”我的树中没有 VSP,但如果 ScrollContentPresenter 执行类似的操作,它会产生我所看到的行为。谢谢。 stackoverflow.com/a/3090616/2970316
-
是的,就是这样,但我觉得我遇到了其他领域。嘿,这只是一条评论。
标签: wpf scrollviewer word-wrap