Scott Chamberlain
Scott Chamberlain

Reputation: 127543

Get Ellipsis to show up on Auto width text

I have the following simple program

<Window x:Class="TextCutoffExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="100" Width="200">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" TextTrimming="CharacterEllipsis"/>
        <Button Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Content="..."/>
    </Grid>
</Window>

When run it produces this

enter image description here

pushing the button outside of the window. If I make the 2nd column Auto and the 1st column * with it looks correctly when the text is too large

enter image description here

However when the text is not too large making the 2nd column auto puts it at the far right.

enter image description here

What I want to happen is the button to be right next to the text

enter image description here

The closest I could get to getting this to work was setting a max width on the text block and having the 1st column set to Auto

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Grid.Column="0" Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" TextTrimming="CharacterEllipsis" 
               MaxWidth="180"/>
    <Button Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Content="..."/>

That gives me the behavior I want, but I don't know what the maximum width will be at compile time in the real code I will be using this in.

What do I need to do to make the button follow the width of the text but if the text becomes too large for the window it will be cut off with ellipsis without setting a fixed max width?

Upvotes: 2

Views: 967

Answers (2)

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

One of my co-workers found a simple workaround, if you wrap the grid in a TextBlock it makes it behave exactly as I wanted.

<Window x:Class="TextCutoffExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="100" Width="200">
    <Grid>
        <TextBlock>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"  TextWrapping="NoWrap" TextTrimming="CharacterEllipsis"/>
                <Button Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="15"  Content="..."/>
            </Grid>
        </TextBlock>
    </Grid>
</Window>

I tried other "base" UI components like a ContentPresenter but none of them showed the behavior I wanted.

Upvotes: 0

paparazzo
paparazzo

Reputation: 45096

If I had seen your less than gracious comment before I pulled this from existing code I would not have given the effort

<Window x:Class="WidthConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:WidthConverter"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:WidthConverterParam x:Key="widthConverter"/>
    </Window.Resources>
    <Grid x:Name="MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="{Binding ElementName=MainGrid, Path=ActualWidth}" Margin="10,0,0,0"/>
        <TextBlock Grid.Column="1" Text="{Binding ElementName=MainGrid, Path=ActualWidth, Converter={StaticResource widthConverter}, ConverterParameter=80}" Margin="10,0,10,0"/>
        <TextBlock Grid.Column="2" Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaabcdefghijklmnop" TextTrimming="CharacterEllipsis" 
               MaxWidth="{Binding ElementName=MainGrid, Path=ActualWidth, Converter={StaticResource widthConverter}, ConverterParameter=80}"/>
        <Button Grid.Column="3" HorizontalAlignment="Left" VerticalAlignment="Top" Content="..."/>
    </Grid>
</Window>

using System.Globalization;

namespace WidthConverter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    [ValueConversion(typeof(double), typeof(double))]
    public class WidthConverterParam : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // value is the total width available

            double otherWidth;
            try
            {
                otherWidth = System.Convert.ToDouble(parameter);
            }
            catch
            {
                otherWidth = 100;
            }
            if (otherWidth < 0) otherWidth = 0;

            double width = (double)value - otherWidth;
            if (width < 0) width = 0;
            return width; // columnsCount;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Upvotes: 1

Related Questions