C# WPF - ScrollViewer + TextBlock问题

21

我有一个ScrollViewer中的TextBlock,希望它能够始终与窗口大小对齐。我需要这个TextBlock满足以下要求:

  • 随着窗口大小调整而自动调整大小,不出现滚动条
  • 当缩小到一定程度时,TextBlock需要保持最小宽度,并且出现滚动条
  • TextWrappingTextTrimming应该适当地工作

如何实现这个功能?

我已经尝试过几种方法,涉及到将ActualWidthActualHeight绑定起来,但是无法让其正常工作。

这应该不难,我可能漏掉了什么关键点吗?

以下是可放入 XamlPad 的代码示例(目前未设置MinWidth):

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <TextBlock TextWrapping="Wrap" Text="Some really long text that should probably wordwrap when you resize the window." />
    </ScrollViewer>
</Window>

请澄清:滚动查看器是否内置于控件模板中?还是外部控制? - Aviad P.
你可以假装它看起来像上面那样。 - jonathanpeppers
2个回答

28

这段代码可行:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ScrollViewer HorizontalScrollBarVisibility="Auto" 
                  VerticalScrollBarVisibility="Auto"
                  Name="Scroller">
        <TextBlock HorizontalAlignment="Stretch"
                   VerticalAlignment="Stretch"
                   MinWidth="100"
                   Width="{Binding ElementName=Scroller, Path=ViewportWidth}"
                   TextWrapping="Wrap"
                   Text="Some really long text that should probably wordwrap when you resize the window." />
    </ScrollViewer>
</Window>

1
是的,那是一种方法,尽管它可能会导致布局引擎在可视树上循环多次,因为宽度绑定发生在渲染之后,这会强制进行另一个布局传递。 - Aviad P.
是的,正确的方法是修改滚动查看器、文本块或中间的某个自定义元素的测量和排列逻辑。自从我写下那个“我正在努力解决它”的评论以来,我一直在苦苦思索。 - Aviad P.
2
我注意到在我的机器上(在我的完整应用程序中,具有复杂的布局),当调整窗口大小时似乎有点卡顿,如果您找到了一种防止额外布局传递的方法 - 那就太好了。 - jonathanpeppers
+1 - 感谢您花时间研究这个问题。如果不进行大规模的代码重写,这可能是最好的解决方案了 :) - Aviad P.
6
谢谢!谢谢!谢谢!哦天啊,我刚花了2个小时寻找解决方案,绑定到ViewportWidth就解决了问题!非常感谢你。 - Kirill Osenkov

2

如果没有更多的细节,我所能提供的最好方法就是提供标准的实现方式。基本上,将您具有最小尺寸的元素(例如图片)托管在滚动查看器中;当滚动查看器调整为足够小以致于元素无法完全适应其中时,它会自动显示滚动条。 例如:

<ScrollViewer>
    <Button MinWidth="100" MinHeight="50"/>
</ScrollViewer>

这在XamlPad中可以运行,但在我的应用程序中却不行。我需要进行一些挖掘来找出原因。 - jonathanpeppers
你想要实现的具体行为是什么?当你在TextBlock上设置MinWidthMinHeight时,它应该正常工作。 - Aviad P.
如果您在XamlPad中尝试上述操作,则TextBlock在调整窗口大小时不会自动调整大小。 - jonathanpeppers
哦,我知道你的意思了,那是由于文本换行引起的。正在处理中 :) - Aviad P.
我没有找到其他的方法,而且说实话它比我最初想象的要复杂得多。ScrollViewer 的测量和排列逻辑(至少可以这么说)并不是微不足道的,模拟它需要大量的工作,并尝试使用 Reflector 弄清楚幕后发生了什么。 - Aviad P.
显示剩余2条评论

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