#wpf #xaml #controltemplate #listviewitem
#wpf #xaml #controltemplate #listviewitem
Вопрос:
Я использую пользовательский селектор стилей в представлении списка, чтобы изменить cornerRadius / BorderThickness для первого и последнего элемента.
Мне нужно иметь эту презентацию с привязкой перечисления к listview
Код представления списка с помощью ItemContainerStyleSelector
<ListView ItemsSource="{Binding ItemsSource, ElementName=Self, Mode=TwoWay}"
FocusVisualStyle="{x:Null}"
BorderThickness="0"
SelectedValue="{Binding SelectedValue, ElementName=Self, Mode=TwoWay}"
HorizontalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Background="Transparent">
<ListView.ItemContainerStyleSelector>
<enumToggleButtonList:FirstLastItemStyleSelector
DefaultStyle="{StaticResource AllItemStyle}"
StyleFirst="{StaticResource FirstItemStyle}"
StyleLast="{StaticResource LastItemStyle}"/>
</ListView.ItemContainerStyleSelector>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid FlowDirection="LeftToRight" Rows="1"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
У меня есть 3 стиля: default / first / last вот так
<Style x:Key="AllItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="0"
BorderThickness="1,1,0,1">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource SelectedBorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource SelectedTextblockListViewItemStyle}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource BorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource TextblockListViewItemStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
<Style x:Key="LastItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="0,5,5,0">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
.... same
</Style>
<Style x:Key="FirstItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="5,0,0,5"
BorderThickness="1,1,0,1">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
.... same
</Style>
И глобальные изменения касаются границы :
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="5,0,0,5"
BorderThickness="1,1,0,1">
Есть какие-либо методы для реорганизования этого, не используя код, лежащий в основе plz? Или другой способ сделать это?
Комментарии:
1. Вам нужно быть более конкретным в отношении того, чего вы пытаетесь достичь. Что вы пытаетесь реорганизовать? Что не работает?
2. Я обновил свою тему, она работает хорошо, но для многих повторений кода стиля требуется лишь небольшое изменение радиуса угла, толщины границы… Я не уверен, что это лучший способ сделать это ^^ ‘
Ответ №1:
Вы можете упростить свои стили, используя прикрепленные свойства. Но для этого требуется создать простой присоединенный класс свойств.
using System.Windows;
namespace SO
{
public static class ListViewItemProperties
{
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.RegisterAttached(
"CornerRadius",
typeof(Thickness),
typeof(ListViewItemProperties),
new PropertyMetadata(new Thickness(0d)));
public static Thickness GetCornerRadius(DependencyObject obj)
{
return (Thickness)obj.GetValue(CornerRadiusProperty);
}
public static void SetCornerRadius(DependencyObject obj, Thickness value)
{
obj.SetValue(CornerRadiusProperty, value);
}
}
}
И есть обновленные (и упрощенные) стили, которые используют присоединенное свойство:
<Style x:Key="AllItemStyle" TargetType="ListViewItem">
<Setter Property="local:ListViewItemProperties.CornerRadius" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
BorderThickness="1,1,0,1"
CornerRadius="{TemplateBinding local:ListViewItemProperties.CornerRadius}"
Style="{StaticResource BorderListViewItemStyle}">
<TextBlock x:Name="TemplateTextBlock"
Style="{StaticResource TextblockListViewItemStyle}"
Text="{Binding}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource SelectedBorderListViewItemStyle}" />
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource SelectedTextblockListViewItemStyle}" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource BorderListViewItemStyle}" />
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource TextblockListViewItemStyle}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter
Event="PreviewMouseLeftButtonDown"
Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
<Style x:Key="LastItemStyle" BasedOn="{StaticResource AllItemStyle}" TargetType="ListViewItem">
<Setter Property="local:ListViewItemProperties.CornerRadius" Value="0,5,5,0" />
</Style>
<Style x:Key="FirstItemStyle" BasedOn="{StaticResource AllItemStyle}" TargetType="ListViewItem">
<Setter Property="local:ListViewItemProperties.CornerRadius" Value="5,0,0,5" />
</Style>
Комментарии:
1. Интересно, спасибо, я увижу, что завтра, при первом тестировании, он на данный момент не работает (с удалением Триггеры> часть, потому что это переопределение стиля границы)
Ответ №2:
Самым простым / привлекательным решением для этого на данный момент является TemplateBinding … Я только что обнаружил, как это работает… учиться сложно .. но путь после проще x)
<Style x:Key="AllItemStyle" TargetType="ListViewItem">
<Setter Property="Border.CornerRadius" Value="0"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="TemplateBorder"
Style="{StaticResource BorderListViewItemStyle}"
CornerRadius="{TemplateBinding Border.CornerRadius}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock x:Name="TemplateTextBlock"
Text="{Binding}"
Style="{StaticResource TextblockListViewItemStyle}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource SelectedBorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource SelectedTextblockListViewItemStyle}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="TemplateBorder" Property="Style" Value="{StaticResource BorderListViewItemStyle}"/>
<Setter TargetName="TemplateTextBlock" Property="Style" Value="{StaticResource TextblockListViewItemStyle}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
<Style x:Key="LastItemStyle" TargetType="ListViewItem" BasedOn="{StaticResource AllItemStyle}">
<Setter Property="Border.CornerRadius" Value="0,10,10,0"/>
</Style>
<Style x:Key="FirstItemStyle" TargetType="ListViewItem" BasedOn="{StaticResource AllItemStyle}">
<Setter Property="Border.CornerRadius" Value="10,0,0,10"/>
<Setter Property="BorderThickness" Value="1,1,0,1"/>