Используйте другой шаблон для последнего элемента в элементе управления WPF
Я использую настраиваемый шаблон в своем элементе управления items, чтобы отобразить следующий результат:
item 1, item 2, item3,
Я хочу изменить шаблон последнего элемента, чтобы результат стал:
item 1, item2, item3
Элемент ItemsControl:
<ItemsControl ItemsSource="{Binding Path=MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text=", "/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Есть ли кто-нибудь, кто может решить проблему? Спасибо!
Ответы
Ответ 1
Я нашел решение для своей проблемы, используя только XAML. Если есть кто-то, кто должен сделать то же самое, используйте это:
<ItemsControl ItemsSource="{Binding Path=MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="comma" Text=", "/>
<TextBlock Text="{Binding}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter TargetName="comma" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Ответ 2
Вы можете использовать DataTemplateSelector, в SelectTemplate() вы можете проверить, является ли элемент последним, а затем вернуть другой шаблон.
В XAML:
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter
ContentTemplateSelector = "{StaticResource MyTemplateSelector}">
В коде позади:
private sealed class MyTemplateSelector: DataTemplateSelector
{
public override DataTemplate SelectTemplate(
object item,
DependencyObject container)
{
// ...
}
}
Ответ 3
Один вопрос... Я вижу, что вы используете ItemsControl
, а не a ListBox
, и что он связан с коллекцией строк и что вы пытаетесь показать только результат текст без форматирования отдельных частей, что заставляет меня задаться вопросом, действительно ли ваш желаемый результат является самой строкой, как указано в вопросе, а не фактическим ItemsControl
как таковым.
Если я прав по этому поводу, рассмотрели ли вы просто использование простой TextBlock
связанной с коллекцией элементов, но через конвертер? Затем внутри конвертера вы добавили бы value
в массив строк, затем в метод Convert
, просто Join
их с помощью запятой в качестве разделителя, который будет автоматически добавлять только между элементами, например..
var strings = (IEnumerable<String>)value;
return String.Join(", ", strings);
Ответ 4
Это решение влияет на последнюю строку и обновляется с изменениями в базовой коллекции:
CodeBehind
Для правильного функционирования преобразователя требуются 3 параметра: текущий элемент, элементcontrol, itemscount и возвращает true, если текущий элемент также является последним элементом:
class LastItemConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
int count = (int)values[2];
if (values != null && values.Length == 3 && count>0)
{
System.Windows.Controls.ItemsControl itemsControl = values[0] as System.Windows.Controls.ItemsControl;
var itemContext = (values[1] as System.Windows.Controls.ContentPresenter).DataContext;
var lastItem = itemsControl.Items[count-1];
return Equals(lastItem, itemContext);
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML
Триггер данных для DataTemplate, который содержит текстовое поле с именем "PART_TextBox":
<DataTemplate.Triggers>
<DataTrigger Value="True" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource LastItemConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" />
<Binding RelativeSource="{RelativeSource Self}"/>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="Items.Count"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Foreground" TargetName="PART_TextBox" Value="Red" />
</DataTrigger>
</DataTemplate.Triggers>
Преобразователь как статический ресурс в Xaml
<Window.Resources>
<local:LastItemConverter x:Key="LastItemConverter" />
</Window.Resources>
SnapShot
И его снимок в действии
Код был добавлен в элементcontrol from этот 'codeproject'
https://www.codeproject.com/Articles/242628/A-Simple-Cross-Button-for-WPF
Обратите внимание на последний текст элемента в красном