0
votes

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

2
What is the purpose of the ViewBox? Can you replace it with some panel, or just add the Textblock directly under the Grid?ShayD
The purpose is to control the size of the text. In my final app, the viewbox is controlled through it's margins and set by percentage.Lasse O
ViewBox is certainly not what you need here. Consider using some Panel or a Border instead.ShayD
Actually i'm using this example now, as it solves another problem. This is based on a Panel, but have the same problem. stackoverflow.com/questions/4542835/…Lasse O
I have updated the description width more realistic usage by my app.Lasse O

2 Answers

1
votes

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.

0
votes

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.