【问题标题】:How do I get rid of this WPF/XAML ListBox Padding?如何摆脱这个 WPF/XAML 列表框填充?
【发布时间】:2014-09-27 23:00:15
【问题描述】:

我在学习 WPF 时遇到了一些麻烦,我已经像这样设置了一个自定义 UserControl:

<UserControl
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:LobbyApp" x:Class="LobbyApp.ChatPanel" 
         mc:Ignorable="d" 
         d:DesignHeight="200" d:DesignWidth="600">
<UserControl.Resources>
    <DataTemplate DataType="{x:Type local:ChatMessage}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition>
                    <ColumnDefinition.Width>Auto</ColumnDefinition.Width>
                    <ColumnDefinition.SharedSizeGroup>Date</ColumnDefinition.SharedSizeGroup>
                </ColumnDefinition>
                <ColumnDefinition>
                    <ColumnDefinition.Width>Auto</ColumnDefinition.Width>
                    <ColumnDefinition.SharedSizeGroup>Who</ColumnDefinition.SharedSizeGroup>
                </ColumnDefinition>
                <ColumnDefinition>
                    <ColumnDefinition.Width>*</ColumnDefinition.Width>
                </ColumnDefinition>
            </Grid.ColumnDefinitions>
            <DataGridCell BorderThickness="0" Content="{Binding Timestamp}" Grid.Column="0" Background="Black" Foreground="LightCyan"/>
            <DataGridCell BorderThickness="0" Content="{Binding Who}" Grid.Column="1" Background="Black" Foreground="LightBlue"/>
            <DataGridCell BorderThickness="0" Grid.Column="2" Background="Black" Foreground="White">
                <TextBox Text="{Binding What, Mode=OneWay}" IsReadOnly="True" TextWrapping="Wrap"/>
            </DataGridCell>
        </Grid>
    </DataTemplate>
</UserControl.Resources>

<ListBox ItemsSource="{Binding History}" SnapsToDevicePixels="True" Background="Magenta" Padding="0"/>

我认为大部分都无关紧要,只是为了完整性而包含它。有趣的是我看到滚动条外的洋红色背景,就像列表框内容一样,它的滚动条实际上​​填充在列表框内。它看起来像这样:

即使列表框大小合理,我也会看到外部洋红色,当您将它缩小到这样时更容易看到。

我已经尝试了每个元素上的每个边距/填充,以消除洋红色,但我似乎做不到。我不知道是什么原因造成的,或者如何“修复”它。我可能会将我的示例简化为最基本的部分,但我认为我会先发布,因为这可能只是一个愚蠢的明显答案。如果是这样,我很抱歉。

【问题讨论】:

    标签: wpf xaml listbox wpf-controls


    【解决方案1】:

    这是因为 ListBox 的 Border Padding 具有硬编码值“1”。

    <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border Name="Bd"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="true"
                            Padding="1">
                        <ScrollViewer Padding="{TemplateBinding Padding}"
                                      Focusable="false">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
    

    所以你可以自己修改模板,或者像下面这样修改它:

    void OnListBoxLoaded(object sender, RoutedEventArgs e)
        {
            Border border = VisualTreeHelper.GetChild((ListBox)sender, 0) as Border;
            if(border != null)
            {
                border.Padding = new Thickness(0);
            }
        }
    

    以上假设您使用的是默认的 windows aero 主题。如果您更改主题,或者确实更改了 aero 主题,它可能会中断。

    【讨论】: