WPF- Как реорганизовать шаблон с несколькими стилями ListViewItem с небольшими изменениями?

#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"/>