自定义 ListBoxItem:去掉边框 + 可点击区域

Customizing ListBoxItem: Getting rid of border + clickable area

我正在定制 ListBoxItem,但遇到了几个问题。

XAML:

<ListBox Grid.Row="1" ItemsSource="{Binding MenuButtonInfoList}"
        SelectedIndex="{Binding SelectedMainMenuIndex, Mode=TwoWay}">
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBox}">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Width" Value="160px" />
            <Setter Property="BorderBrush" Value="{StaticResource PrimaryColor}" />
            <Setter Property="BorderThickness" Value="0, 1, 0, 0" />
        </Style>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="OverridesDefaultStyle" Value="True" />
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="MenuButtonBorder" SnapsToDevicePixels="True"
                                BorderBrush="{StaticResource PrimaryColor}" BorderThickness="0, 0, 0, 1">
                            <StackPanel Orientation="Vertical" Height="120px">
                                <Image Source="{Binding ImageFilePath}" Height="30" Width="30" />
                                <Label x:Name="MenuButtonLabel" Content="{Binding Label}" 
                                        FontSize="{StaticResource Title1FontSize}"
                                        Foreground="{StaticResource PrimaryColor}" />
                            </StackPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter TargetName="MenuButtonBorder" Property="Background" Value="{StaticResource PrimaryColor}" />
                                <Setter TargetName="MenuButtonLabel" Property="Foreground" Value="{StaticResource HighlightColor}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
</ListBox>

How do I get the open area to also cause a change in selection?

在项目模板的 StackPanel 上设置 Background="Transparent"。这将使整个面板都可以测试。

There's a 1px line between the ListBox container and the ListBoxItem's that I'm not able to get rid of. How do I get rid of it?

覆盖 ListBox 模板以删除 1px 填充:

<ControlTemplate TargetType="{x:Type ListBox}">
  <Border Name="Bd"
          Background="{TemplateBinding Background}"
          BorderBrush="{TemplateBinding BorderBrush}"
          BorderThickness="{TemplateBinding BorderThickness}"
          SnapsToDevicePixels="true">
     <!-- Padding="1" (removed) -->
    <ScrollViewer Padding="{TemplateBinding Padding}"
                  Focusable="false">
      <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </ScrollViewer>
  </Border>
  <ControlTemplate.Triggers>
    <Trigger Property="IsEnabled"
              Value="false">
      <Setter TargetName="Bd"
              Property="Background"
              Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
    </Trigger>
    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="IsGrouping" Value="true" />
        <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
      </MultiTrigger.Conditions>
      <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
    </MultiTrigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

Template 属性 的 Setter 中放置上面的 ListBox 样式。