【问题标题】:WPF TextBlock overflow in Viewbox视图框中的 WPF TextBlock 溢出
【发布时间】:2015-02-21 15:40:47
【问题描述】:

我想在带有 TextTrimming 的 ViewboxPanel 控件中拥有一个 TextBlock,但为了做到这一点,TextBlock 必须有一个宽度。但是为什么在ViewboxPanel中宽度与显示的宽度无关?

<Window x:Class="SizeTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:converters="clr-namespace:SizeTest.Utils.Converters;assembly=SizeTest.Utils"
        xmlns:controls="clr-namespace:SizeTest.Utils.Controls;assembly=SizeTest.Utils"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <converters:MarginConverter x:Key="MarginConverter"/>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <controls:ViewboxPanel HorizontalAlignment="Left">
            <controls:ViewboxPanel.Margin>
                <MultiBinding Converter="{StaticResource MarginConverter}" ConverterParameter="0;40;0;40">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}" Path="ActualHeight" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}" Path="ActualWidth" />
                </MultiBinding>
            </controls:ViewboxPanel.Margin>
            <TextBlock Text="fgghgfhdfgfgsdfdsfdsfdsfsdf" Width="130" TextTrimming="CharacterEllipsis" />
        </controls:ViewboxPanel>

    </Grid>
</Window>

控制:

public class ViewboxPanel : Panel
        {
            private double scale;

            protected override Size MeasureOverride(Size availableSize)
            {
                double height = 0;
                Size unlimitedSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
                foreach (UIElement child in Children)
                {
                    child.Measure(unlimitedSize);
                    height += child.DesiredSize.Height;
                }
                scale = availableSize.Height / height;

                return availableSize;
            }

            protected override Size ArrangeOverride(Size finalSize)
            {
                Transform scaleTransform = new ScaleTransform(scale, scale);
                double height = 0;
                foreach (UIElement child in Children)
                {
                    child.RenderTransform = scaleTransform;
                    child.Arrange(new Rect(new Point(0, scale * height), new Size(finalSize.Width / scale, child.DesiredSize.Height)));
                    height += child.DesiredSize.Height;
                }

                return finalSize;
            }
        }

ViewboxPanel 由边距和百分比控制。但是为什么 TextBlock 的 130 的宽度与 ViewboxPanel 的 525 的宽度匹配(按窗口宽度)?

我希望能够调整窗口大小,并且文本块的宽度应该跟随,以便通过修剪来显示/隐藏文本。所以文本块的宽度应该绑定到它所在的网格的宽度,像这样:

Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Path=ActualWidth}"

但我不明白为什么 525 不正确!?

【问题讨论】:

  • ViewBox 的用途是什么?你可以用一些面板替换它,还是直接在网格下添加文本块?
  • 目的是控制文字的大小。在我的最终应用中,视图框是通过其边距控制并按百分比设置的。
  • ViewBox 肯定不是你需要的。考虑改用一些面板或边框。
  • 其实我现在正在使用这个例子,因为它解决了另一个问题。这是基于面板的,但有同样的问题。 stackoverflow.com/questions/4542835/…
  • 我更新了描述宽度,让我的应用更真实地使用。

标签: c# wpf xaml


【解决方案1】:

您似乎误解了ViewBox control 的用途。从 MSDN 上的链接页面:

定义一个内容装饰器,它可以拉伸和缩放单个子元素以填充可用空间

为了得到你想要的改变字符省略号开始点的效果,你需要改变TextBlockWidth,而不是ViewBox

【讨论】:

  • 我没有改变视图框的宽度,只是改变它的高度,以便控制文本的大小。
  • 你需要改变TextBlock的宽度
  • 是的.. 那不是问题。问题是,为什么宽度中的 83 像素显示为窗口/网格宽度的 100%?
  • 如果我通过绑定设置文本块的宽度,它会起作用,但我需要了解为什么 83 在这种情况下是正确的,以便将其绑定到某些宽度。
  • 阅读 MSDN 上的链接页面。它与 83 像素无关,而是与 ViewBox.StretchViewBox.StretchDirection 属性的值有关。我什至将描述的相关部分加粗,以强调 ViewBox 旨在填充可用空间而不管大小。
【解决方案2】:

在您的情况下,视图框会尝试缩放其中的子级,因此,如果您将文本块的宽度设置为 83,则视图框会根据父级的实际宽度和高度来保持控件缩放的比例容器。它永远不会截断您的文本块,因为它会放大和缩小文本块以保持文本块的比例,因此如果窗口没有足够的空间来显示文本块的内容,则视图框会将其缩小,反之亦然。

我认为如果你想使用视图框修剪文本块的内容,你应该尝试将 texblock 的宽度绑定到窗口的宽度

<Window x:Class="SizeTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Name="WinName">
<Grid>
    <Viewbox Height="100" HorizontalAlignment="Left">
        <TextBlock Text="fgghgfhdfgfgdsfdsf" Width="{Binding Path=ActualWidth, ElementName=WinName}" TextTrimming="CharacterEllipsis" />
    </Viewbox>
</Grid>

但在这种情况下,视图框不会对您的文本块进行任何更改:它不会被缩放

如果可以满足,您可以尝试设置Stretch="UniformToFill",但在这种情况下它不会修剪您的文本。

但我认为这不是最好的方法,你一定是误解了viewbox的目标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多