简体   繁体   中英

WPF TextBlock overflow in Viewbox

I want to have a TextBlock in the ViewboxPanel control with TextTrimming, but in order to do so, the TextBlock must have a width. But how come the width has nothing to do with the shown width when in the 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>

Control:

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;
            }
        }

The ViewboxPanel is controlled by margin and percentage. But why does the width of 130 of the TextBlock match the width of the ViewboxPanel which is 525 (by the window width)?

I want to be able to resize the window and the width of the textblock should follow so it shows/hides the text by trimming it. So the Width of the textblock should be bind to the width of the grid its in, like this:

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

But i can't see why 525 wouldn't be correct!?

You seem to have misunderstood the purpose of the ViewBox control . From the linked page on MSDN:

Defines a content decorator that can stretch and scale a single child to fill the available space .

In order to get your desired effect of changing what point the character ellipsis starts, you need to change the Width of the TextBlock , not the ViewBox .

In your situation the viewbox, tries to scale the child inside it and so, if you set the width of the textblock to 83, the viewbox mantain the proportion of the control scaling it according to the actual width and height of the parent container. It will never truncate your textblock because it will zoom it in and out tring to maintain the proportion of the textblock and so if the window hasn't enough space to display the content of the textblock the viewbox will zoom it out and vice versa.

I think that if you want to use the viewbox trimming the content of the textblock you should try to bind the width of the texblock to the width of the window

<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>

but in this case the viewbox doesn't make any change to your textblock: it won't be scaled .

If it can satisfy, you could try to set Stretch="UniformToFill" but in this case it won't trim your text.

But i don't think it is not the best approach, you must have been misunderstood the target of the viewbox.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM