CharacterEllipsis не работает внутри ItemsControl WPF
Я пытаюсь установить CharacterEllipsis
на текст внутри DataTemplate
из ItemsControl
,
<Window x:Class="CustomPanel.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomPanel;assembly="
Title="Window1" Height="400" Width="400">
<Window.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>
</Style>
<DataTemplate DataType="{x:Type local:Person}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"
Margin="100,0,0,0"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding Persons}"
Grid.Column="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
Я также попытался установить ширину ItemsControl
, StackPanel
и TextBlock
сам.
Есть идеи?
РЕДАКТИРОВАТЬ
Чтобы подчеркнуть, что это не проблема Style
или StackPanel
Я удалил оба, и это все еще не работает
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
Margin="100,0,0,0"
Width="200"/>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Persons}"/>
</Grid>
осветление
Это прекрасно работает, когда текст слишком велик, но я хочу, чтобы он работал, когда окно также изменяется в меньшую ширину.
4 ответа
DataTemplate не будет выбирать стиль из окна, поскольку он не находится в этой области. Переместить стиль внутрь DataTemplate.Resources
Или же Application.Resources
так что он может быть выбран TextBlock внутри DataTemplate.
Во-вторых, вы обернули TextBlock внутри StackPanel, что дает его бесконечный размер для расширения. Итак, удалите Stackpanel, которая оборачивает TextBlock.
В-третьих, ограничьте ширину ItemsControl или установите MaxWidth по своему усмотрению.
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<DataTemplate.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
</Style>
</DataTemplate.Resources>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Persons}" Width="30">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
ОБНОВИТЬ:
Если вы хотите, чтобы он работал для изменения размера окна, вместо установки ширины, установите максимальную ширину в TextBlock:
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Text="{Binding Name}" MaxWidth="200"
TextTrimming="CharacterEllipsis"/>
</DataTemplate>
</Window.Resources>
<ItemsControl Margin="100,0,0,0" ItemsSource="{Binding Persons}"/>
добавлять x:Key
стиль и установить стиль TextBlock, как это:(Рохит Ватс сказал причину)
<Style x:Key="tb" TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>
</Style>
<DataTemplate DataType="{x:Type local:Person}">
<StackPanel Orientation="Horizontal">
<TextBlock Width="90" Style="{DynamicResource tb}" Text="{Binding Name}"
Margin="100,0,0,0"/>
</StackPanel>
</DataTemplate>
а затем удалите панель стека или установите ширину текстового блока.
результат:
и мой тестовый код:
Persons = new List<Person>();
Person p = new Person();
p.Name="One\ntwo two\nThree Three Three\nfour four four four";
Persons.Add(p);
другой результат: (изменить размер окна)
код:
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Style="{DynamicResource tb}" Text="{Binding Name}"
Margin="100,0,0,0"/>
</DataTemplate>
Короткий ответ:
Удалите свою стековую панель из вашей таблицы данных:
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Text="{Binding Name}" TextTrimming="CharacterEllipsis"/>
</DataTemplate>
Панель стека занимала все необходимое пространство, поэтому обрезка не работала.
Длинный ответ:
Пример настройки datacontext:
<Window.DataContext>
<local:PersonsViewModel/>
</Window.DataContext>
Простой вм:
public class PersonsViewModel : INotifyPropertyChanged
{
private ObservableCollection<Person> persons = new ObservableCollection<Person> { new Person { Name = "Bjarne balblablalblalbal balbalbalballblalbla" }, new Person { Name = "Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla" }, new Person { Name = "Turid" } };
public ObservableCollection<Person> Persons
{
get { return persons; }
set
{
if (Equals(value, persons)) return;
persons = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator] // No R#? Comment this line out
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Класс Person также должен реализовывать INotifyPropertyChanged, чтобы сигнализировать об изменении свойства.
public class Person : INotifyPropertyChanged
{
private string name;
public String Name
{
get { return name; }
set
{
if (value == name) return;
name = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
ура
Stian
Это довольно смелое и неверное утверждение. Даже не копируя ваш код в новый проект, я могу понять, почему у вас такая проблема. Для того, чтобы CharacterEllipsis
работать, TextBlock
необходимо иметь некоторое ограничение на его Width
... иначе как бы WPF узнал, когда следует запустить эффект многоточия персонажа?
Одним из решений было бы установить точный Width
на TextBlock
:
<TextBlock Text="{Binding Name}" Margin="100,0,0,0" Width="200" />
Конечно, это не будет удобно для многих людей, поэтому альтернативой было бы не использовать StackPanel
как ItemsPanelTemplate
(или в DataTemplate
) потому что они позволят TextBlock
расти бесконечно.
ОБНОВЛЕНИЕ >>>
Хорошо, у вас есть три возможных решения, потому что Style
выходит за рамки сгенерированного DataTemplate
элементы:
а) Переместить Style
в DataTemplate.Resources
:
<DataTemplate DataType="{x:Type local:Person}">
<DataTemplate.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextBlock.TextTrimming" Value="CharacterEllipsis" />
</Style>
</DataTemplate.Resources>
<TextBlock Text="{Binding Name}" Margin="100,0,0,0"/>
</DataTemplate>
б) Добавить TextTrimming
собственность прямо на TextBlock
:
<TextBlock Text="{Binding}" TextTrimming="CharacterEllipsis" Margin="100,0,0,0"/>
в) установить Style
на TextBlock
в явном виде:
<Style x:Key="YourStyle" TargetType="{x:Type TextBlock}">
<Setter Property="TextBlock.TextTrimming" Value="CharacterEllipsis" />
</Style>
<TextBlock Style="{StaticResource YourStyle}" Text="{Binding}" Margin="100,0,0,0"/>