2

我一直试图让某些东西在 Windows 8 Metro 风格的应用程序中工作,但我无法获得正确的属性来让它工作。这就是我想要发生的事情:

我有一个包含 StackPanel 的 ScrollViewer。RichTextBox 被添加到堆栈面板(从服务器流式传输文本数据)。它像控制台一样有效地工作。所以我的布局大致是这样的:

<ScrollViewer>
  <StackPanel x:Name="outputStackPanel"/>
</ScrollViewer>

我想要的行为是这样的:我希望文本在屏幕尺寸的水平方向上均匀缩放,然后在 ScrollViewer 中垂直滚动。也就是说,我使用的字体是定宽字体,无论屏幕大小,我都希望出现相同数量的ascii字符。

此外,我可以在应用程序中选择将文本换行或不将文本换行到屏幕上。这意味着,当文本换行时,它应该换行到固定的屏幕宽度,但如果不是,则 ScrollViewer 应该可以水平滚动,但在任何时候,水平滚动时应该可以看到大致相同数量的字符。

我已经尝试了几种方法来做到这一点,但都没有成功。我尝试添加一个 ViewBox,如下所示:

<ScrollViewer>
  <Viewbox Stretch="UniformToFill" StretchDirection="UpOnly">
    <StackPanel x:Name="outputStackPanel" />
  </ViewBox>
</ScrollViewer>

虽然这似乎可以让文本以正确的大小出现,但它不允许文本在文本换行打开时换行。内容只是在右侧被截断。

我目前的解决方法是检查屏幕分辨率并对字体大小进行粗略估计以使其正确显示,但这并不理想,因为它并不精确,因此不同的分辨率会得到截然不同的可见字符数量,并且对于出于此应用程序的目的,可见字符的数量很重要。

4

2 回答 2

4

我已经能够让它工作,但不幸的是,我认为没有一个答案可以自动适用于任何字体。我可能是错的,但这是我如何让它工作的:

我选择了一个固定宽度的字体(Consolas)和一个特定的大小。我认为大小并不重要。

选择字体大小后,我将 RichTextBlock 放入 ViewBox 并计算出设置 RichTextBlock 所需的 WIDTH 以在屏幕上获得我想要的确切字符数(或列数)。在字体大小为 13.333 时,要获得正好 60 列,我需要 440 的宽度。

在 ViewBox 内使用 13.333 字体大小和 440 的固定宽度,无论屏幕分辨率或方向如何以及文本换行,我总是能够准确地获得 60 列。既然这行得通,我需要在禁用自动换行的情况下解决您的问题。

您希望文本能够从屏幕上流出并允许用户向任一方向平移,但您始终需要固定数量的列(在我的示例中为 60)。为此,我从 RichTextBox 中删除了固定宽度,并确定了 ScrollViewer 需要设置的缩放级别才能始终获得 60 列宽。事实证明,缩放级别是当前屏幕宽度除以 440(我在上面为这个特定字体和大小想出的神奇宽度)。

所以,这里是 xaml:

    <ScrollViewer x:Name="Scroller" ZoomMode="Disabled" HorizontalScrollBarVisibility="Visible" >
        <RichTextBlock x:Name="TextBlock">
            <Paragraph FontSize="13.333" FontFamily="Consolas">
                <Run Text="…" FontFamily="Consolas"/>
            </Paragraph>
        </RichTextBlock>
    </Viewbox>
</ScrollViewer>

对于自动换行:

TextBlock.Width=440
Scroller. ZoomToFactor(1.0f)

对于自动换行关闭:

TextBlock.Width=Auto
Scroller.ZoomToFactor((float)Window.Current.Bounds.Width / 440);

It’s important to change the zoom level whenever the window size changes. This could be because the user rotated the device, because they connected an external monitor, because you’ve gone into snapped view, etc. You can get notified whenever this happens by subscribing to the Window.Current.SizeChanged event. Inside the event, be sure to use the parameter passed to you because the window hasn’t actually changed size yet at this point. So:

void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
    Scroller.ZoomToFactor((float)e.Size.Width / 440);
}

Finally, obviously the Width of 440 is tied to that particular font, font size and the fact that I always want 60 columns displayed. Once I figured it out, it should never change on any display size as long as I use the same font and font size. If you want to allow the user to pick different fonts, you’re going to have to figure out a way to calculate that dynamically. I couldn’t find any answer for this in my 20 minutes of searching. Maybe someone else can find that.

于 2012-07-03T21:57:57.113 回答
0

你可以试试 Viewbox 控件。它会调整其内容的大小,因此您不必担心屏幕分辨率等问题。

C# 的文档在这里。还有一个JS版本。

这是一个关于扩展 Metro Apps很好的 MS 指南,您可以查看其他一些想法。

于 2012-07-02T15:10:55.887 回答