style color bar wpf templates itemscontrol

color - Use una plantilla diferente para el último elemento en un control de elementos WPF



wpf window title bar color (4)

Esta solución afecta a la última fila y se actualiza con los cambios en la colección subyacente:

Código detrás

El convertidor requiere 3 parámetros para funcionar correctamente: el elemento actual, el control de elementos, el número de elementos y devuelve verdadero si el elemento actual también es el último elemento:

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

El activador de datos para una plantilla de datos, que incluye un cuadro de texto llamado ''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>

El convertidor como recurso estático en el Xaml.

<Window.Resources> <local:LastItemConverter x:Key="LastItemConverter" /> </Window.Resources>

Instantánea

Y una instantánea de ella en acción.

El código se ha agregado al control de elementos de este ''codeproject'' https://www.codeproject.com/Articles/242628/A-Simple-Cross-Button-for-WPF

Note el texto del último artículo en rojo.

Estoy usando una plantilla personalizada en mi control de elementos para mostrar el siguiente resultado:

item 1, item 2, item3,

Quiero cambiar la plantilla del último elemento para que el resultado se convierta en:

item 1, item2, item3

El 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>

¿Hay alguien que pueda dar una solución a mi problema? ¡Gracias!


He encontrado la solución para mi problema usando solo XAML. Si hay alguien que necesita hacer lo mismo, usa esto:

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


Puede usar DataTemplateSelector , en el método SelectTemplate() puede verificar si el elemento es el último y luego devolver otra plantilla.

En XAML:

<ItemsControl.ItemTemplate> <DataTemplate> <ContentPresenter ContentTemplateSelector = "{StaticResource MyTemplateSelector}">

En el código detrás:

private sealed class MyTemplateSelector: DataTemplateSelector { public override DataTemplate SelectTemplate( object item, DependencyObject container) { // ... } }


Una pregunta ... veo que estás usando un ItemsControl en lugar de decir un ListBox y que parece estar vinculado a una colección de cadenas, y que solo intentas mostrar el texto resultante sin formatear las partes individuales, lo que me hace preguntarme si su salida deseada es en realidad la propia cadena como se mencionó en la pregunta, y no un ItemsControl real per se.

Si tengo razón al respecto, ¿ha considerado simplemente el uso de un TextBlock simple vinculado a la colección de elementos, pero se ha alimentado a través de un convertidor? Luego, dentro del convertidor, convertiría el value en una matriz de cadenas, luego, en el método Convert , simplemente Join usando una coma como separador que automáticamente, solo los agregará entre elementos, como así ...

var strings = (IEnumerable<String>)value; return String.Join(", ", strings);