2017-01-20 3 views
0

У меня есть настраиваемый элемент управления, который содержит TextBlock и Ellipse. Я хочу, чтобы этот Эллипс был помещен в положение, где заканчивается TextBlock. Если есть недостаток в пространственном тексте, необходимо обрезать, и Эллипс должен оставаться на своем месте. Я создал очень простой пример, чтобы проиллюстрировать проблему.Как разместить любой элемент пользовательского интерфейса в конце текста, который обрезается

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 получают такую ​​же ширину, как окно приложения имеет и некоторые тексты написаны для них - короткий и длинный.

Вот как этот элемент управления выглядит следующим образом:

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

Он работает нормально, если текст ширина меньше, чем ширина управления. Если текст длинный и занимает больше места, он выходит за окно, Ellipse не отображается, если вы не расширили ширину окон. Когда первая ширина столбца изменяется на «*»:

<ColumnDefinition Width="*"/> 
<ColumnDefinition Width="20" MinWidth="20"/> 

ситуация, чем в то время как текст занимает больше ширины, чем окна, текст быть обрезан и Ellipse находится в правильном месте. Но если текст короткий, Ellipse не будет размещен сразу после текста, а в конце окна.

Image illustrating the problem

Как я могу добиться этого?

ответ

1

Я немного поиграл с вашим кодом, чтобы найти решение. Как вы узнали, настройка ColumnDefinition Width="Auto" не будет работать, потому что она сообщает TextBlock, что у нее столько места, сколько нужно, поэтому она никогда не будет обрезана. Таким образом, установка ColumnDefinition Width="*" - это правильный путь, но, как небольшая деталь, измените свойство HorizontalAlignment всего Grid на 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 дает мне поведение, которое вы хотели бы иметь.

+0

omg, что было все об этом горизонтальном aligment ... спасибо – RTDev

1

Вы можете попробовать использовать 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 - она ​​будет меняться автоматически, даже без этого события.

+0

спасибо за помощь, хотя я отметил ответ schumi1331 как ответ, потому что он лучше подходит для дизайна, который у меня уже есть – RTDev

+1

@RTDev Нет проблем с этим.Обратите внимание, что технически на вашем снимке * Что я хочу * показывает, что фиолетовый фон должен быть через всю ширину окна - это разница между этими двумя решениями (хотя, конечно, это может быть достигнуто и другими способами). Все зависит от того, чего вы хотите достичь. – Romasz

+0

да, действительно, но я всегда могу обернуть весь элемент управления в еще одну сетку, чтобы иметь цвет - моя фактическая ситуация проще, потому что этот элемент управления не будет иметь никакого фона вообще - это просто для демонстрации, и мой фактический макет далеко более сложный - я попытался принять участие, что показывает мой isse – RTDev

Смежные вопросы