如何确保 ListView 显示完整的项目

How to ensure that ListView shows complete items

我一直在遵循有关如何完全显示 ListView 项目的指南和 other SO posts,但它无法按预期工作。为了演示,我创建了这个非常简单的示例:

XAML:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <ResourceDictionary>
            <Style TargetType="ListView">
                <Setter Property="Height" Value="150"/>
                <Setter Property="Width" Value="50"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
                <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
                <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
            </Style>
            <Style TargetType="ListViewItem">
                <Setter Property="Height" Value="30"/>
                <Setter Property="Width" Value="50"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
            </Style>
            <Style TargetType="TextBox">
                <Setter Property="Height" Value="30"/>
                <Setter Property="Width" Value="50"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <TextBox PreviewMouseDown="textBox_PreviewMouseDown"  Text="5" />

        <Popup x:Name="popup"
               AllowsTransparency="True"
               PlacementTarget="{Binding ElementName=textBox}"
               Placement="Center"
               StaysOpen="False"
               >
            <ListView>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
                <ListViewItem Content="5"/>
            </ListView>
        </Popup>
    </Grid>
</Window>

代码隐藏:

using System.Windows;
using System.Windows.Input;

namespace WpfApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void textBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            popup.IsOpen = true;
        }
    }
}

此应用程序在启动时显示如下文本框:

当我单击 TextBox 时,弹出窗口打开并显示包含 5 个可见项目的 ListView:

现在如您所见,中间项没有精确覆盖 TextBox 中的“5”,这正是我想要的。另请注意,列表中最后一个“5”下的 space 没有达到应有的程度。

ListView 的高度是 ListViewItem 和 TextBox 高度的倍数 (5 * 30 = 150),根据我的理解,这应该是正确的高度。

谁能告诉我我做错了什么/遗漏了什么 - ListView 的中间“5”正好覆盖了 TextBox 中的“5”?

wpf TextBox 有一些填充 space 用于像 'g' 这样的字母(抱歉,不知道基线以下这些额外像素的正确术语:-))

所以您可以尝试调整文本框的填充,如下所示:

是否需要编辑条目?如果不是,请使用 TextBlock 代替 VerticalAlignment="Center"。这应该渲染得更好...

你也可以在你的Style中定义你的ListViewItem的datatemplate,我觉得默认是"ContentPresenter",转成TextBox应该直接在上面渲染。

在显示 ListView 时,我会关闭 TextBox 的可见性。因为 "middle" 项目可能是“6”...如果我是对的,你正在为值构建一些滚动选择器..

编辑:

经过一些测试,ListView/ListBox 控件实现了一些内部填充。除非你完全想重新设计它们,否则最好的办法是设置

HorizontalOffset=" -2"
VerticalOffset="-2"

弹出控件...或根据需要。骇人听闻?绝对:)

我猜你也会为你的生产代码使用一些数据绑定,这只是一个设计测试:)