WPF ListBox 显示由 DataGrid 创建的空行

WPF ListBox showing empty row created by DataGrid

我将 DataGridListbox 绑定到同一个 ObservableCollection:

public ObservableCollection<Contact> contacts = new ObservableCollection<Contact>();
CntGrid.ItemsSource = contacts;
CntListBox.ItemsSource = contacts;
<DataGrid x:Name="CntGrid" 
IsReadOnly="False"
CanUserAddRows="True"
CanUserDeleteRows="True"/>

<ListBox x:Name="CntListBox"/>

问题是 DataGrid 允许添加项目(我想保留此功能)导致 ListBox 也显示空行。我不希望我的 ListBox 在末尾显示这个空行。

我能以某种方式修改我的 ListBox 来解决这个问题吗?

DataGrid 中的空行是一个 NewItemPlaceholder。它的类型与 Contact 不同。所以我建议使用转换器将其隐藏在 ListBox 中:

public class ObjectTypeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var t = parameter as Type;
        if (value == null || t == null)
            return false;

        return t.IsAssignableFrom(value.GetType());
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

在 ListBoxItem 样式中使用该转换器来检查项目的类型并在类型不匹配时隐藏它们:

<Window.Resources>
    <local:ObjectTypeConverter x:Key="tc"/>
</Window.Resources>

<ListBox x:Name="CntListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Converter={StaticResource tc}, ConverterParameter={x:Type local:Contact}}" 
                             Value="False">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

这将隐藏列表框中的 {NewItemPlaceholder} 项:

            <ListBox x:Name="CntListBox">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding}" Value="{x:Static CollectionView.NewItemPlaceholder}">
                                <Setter Property="UIElement.Visibility" Value="Collapsed"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ListBox.ItemContainerStyle>
             </ListBox>