Reputation: 127543
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
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
However when the text is not too large making the 2nd column auto puts it at the far right.
What I want to happen is the button to be right next to the text
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
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
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