如何将任何 UI 元素放置在被修剪的文本末尾
How to place any UI element at the end of text that is trimmed
我有一个包含 TextBlock 和 Ellipse 的自定义控件。
我想将此 Ellipse 放置在 TextBlock 结束的位置。如果缺少 space 文本应该被修剪并且椭圆应该保留在它的位置。我创建了非常简单的示例来说明问题。
MainPage.xaml.cs:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainGrid" HorizontalAlignment="Stretch">
<Grid Height="50">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<local:TextWithEllipse x:Name="Control1" Grid.Row="0"/>
<local:TextWithEllipse x:Name="Control2" Grid.Row="1"/>
</Grid>
</Grid>
MainPage.cs:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
SizeChanged += OnSizeChanged;
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
Control1.Text = "One two three four five six seven eight nine ten One two three four five six seven eight nine ten";
Control2.Text = "Short text";
}
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Control1.Width = e.NewSize.Width;
Control2.Width = e.NewSize.Width;
}
}
完成了什么:TextWithEllipse 控件的宽度与应用程序 window 的宽度相同,并且向它们写入了一些文本 - 短文本和长文本。
此控件如下所示:
TextWithEllipse.xaml.cs:
<UserControl
x:Class="TextResize.TextWithEllipse"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid Height="20" HorizontalAlignment="Stretch" Background="MediumPurple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="20" MinWidth="20"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" x:Name="TestTitle"
TextTrimming="CharacterEllipsis" FontSize="16"/>
<Ellipse Width="20" Height="20" Fill="Red" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
TextWithEllipse.cs:
public sealed partial class TextWithEllipse : UserControl
{
public TextWithEllipse()
{
InitializeComponent();
}
public string Text
{
get { return TestTitle.Text; }
set { TestTitle.Text = value; }
}
}
如果文本宽度小于控件宽度,它工作正常。如果文本很长并且需要更多 space,它会超出 window,除非您扩展 windows 宽度,否则不会显示椭圆。
当第一个 Column width 更改为 '*' 时:
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" MinWidth="20"/>
情况是当文本比 window 宽度更大时,文本正在被修剪并且 Ellipse 在正确的位置。但是如果文字很短,Ellipse不会放在正文之后,而是放在window.
的末尾
我怎样才能做到这一点?
您可以尝试使用 RelativePanel:
<RelativePanel HorizontalAlignment="Stretch" Height="20">
<TextBlock HorizontalAlignment="Stretch" x:Name="TestTitle" TextTrimming="CharacterEllipsis" FontSize="16" Padding="0,0,20,0"/>
<Ellipse Width="20" Height="20" Fill="Red" RelativePanel.AlignRightWith="TestTitle"/>
</RelativePanel>
您也不需要在 OnSizeChanged 中更改宽度 - 即使没有此事件它也会自动更改。
我仔细研究了您的代码以找到解决方案。正如您发现设置 ColumnDefinition Width="Auto"
不起作用,因为它告诉 TextBlock
它拥有所需的 space,因此它永远不会 trim。所以设置ColumnDefinition Width="*"
是正确的做法,但是作为一个小细节,把整个Grid
的HorizontalAlignment
属性改成Left
,因为这样整个Grid
只会在需要时拉伸(当您有很多文本时会发生这种情况)。整个代码将是:
<Grid Height="20" HorizontalAlignment="Left" Background="MediumPurple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" MinWidth="20"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" x:Name="TestTitle"
TextTrimming="CharacterEllipsis" FontSize="16"/>
<Ellipse Width="20" Height="20" Fill="Red" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
这至少在 XAML Designer 中为我提供了您想要的行为。
我有一个包含 TextBlock 和 Ellipse 的自定义控件。 我想将此 Ellipse 放置在 TextBlock 结束的位置。如果缺少 space 文本应该被修剪并且椭圆应该保留在它的位置。我创建了非常简单的示例来说明问题。
MainPage.xaml.cs:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainGrid" HorizontalAlignment="Stretch">
<Grid Height="50">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<local:TextWithEllipse x:Name="Control1" Grid.Row="0"/>
<local:TextWithEllipse x:Name="Control2" Grid.Row="1"/>
</Grid>
</Grid>
MainPage.cs:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
SizeChanged += OnSizeChanged;
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
Control1.Text = "One two three four five six seven eight nine ten One two three four five six seven eight nine ten";
Control2.Text = "Short text";
}
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Control1.Width = e.NewSize.Width;
Control2.Width = e.NewSize.Width;
}
}
完成了什么:TextWithEllipse 控件的宽度与应用程序 window 的宽度相同,并且向它们写入了一些文本 - 短文本和长文本。
此控件如下所示:
TextWithEllipse.xaml.cs:
<UserControl
x:Class="TextResize.TextWithEllipse"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid Height="20" HorizontalAlignment="Stretch" Background="MediumPurple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="20" MinWidth="20"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" x:Name="TestTitle"
TextTrimming="CharacterEllipsis" FontSize="16"/>
<Ellipse Width="20" Height="20" Fill="Red" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
TextWithEllipse.cs:
public sealed partial class TextWithEllipse : UserControl
{
public TextWithEllipse()
{
InitializeComponent();
}
public string Text
{
get { return TestTitle.Text; }
set { TestTitle.Text = value; }
}
}
如果文本宽度小于控件宽度,它工作正常。如果文本很长并且需要更多 space,它会超出 window,除非您扩展 windows 宽度,否则不会显示椭圆。 当第一个 Column width 更改为 '*' 时:
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" MinWidth="20"/>
情况是当文本比 window 宽度更大时,文本正在被修剪并且 Ellipse 在正确的位置。但是如果文字很短,Ellipse不会放在正文之后,而是放在window.
的末尾我怎样才能做到这一点?
您可以尝试使用 RelativePanel:
<RelativePanel HorizontalAlignment="Stretch" Height="20">
<TextBlock HorizontalAlignment="Stretch" x:Name="TestTitle" TextTrimming="CharacterEllipsis" FontSize="16" Padding="0,0,20,0"/>
<Ellipse Width="20" Height="20" Fill="Red" RelativePanel.AlignRightWith="TestTitle"/>
</RelativePanel>
您也不需要在 OnSizeChanged 中更改宽度 - 即使没有此事件它也会自动更改。
我仔细研究了您的代码以找到解决方案。正如您发现设置 ColumnDefinition Width="Auto"
不起作用,因为它告诉 TextBlock
它拥有所需的 space,因此它永远不会 trim。所以设置ColumnDefinition Width="*"
是正确的做法,但是作为一个小细节,把整个Grid
的HorizontalAlignment
属性改成Left
,因为这样整个Grid
只会在需要时拉伸(当您有很多文本时会发生这种情况)。整个代码将是:
<Grid Height="20" HorizontalAlignment="Left" Background="MediumPurple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20" MinWidth="20"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" x:Name="TestTitle"
TextTrimming="CharacterEllipsis" FontSize="16"/>
<Ellipse Width="20" Height="20" Fill="Red" Grid.Column="1" HorizontalAlignment="Left"/>
</Grid>
这至少在 XAML Designer 中为我提供了您想要的行为。