我可以查看 Visibility = Collapsed 的 WPF ComboBoxItem。这是一个 WPF 错误吗?

I can view a WPF ComboBoxItem with Visibility = Collapsed. Is it a WPF bug?

如果我将 ComboBoxItem Visibility 设置为 Collapsed 那么当我打开下拉菜单时我将看不到它...但是我可以 select 使用按键!这是一个错误还是我遗漏了什么?

<Window x:Class="ComboTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <ComboBox>
            <ComboBoxItem>Element 1</ComboBoxItem>
            <ComboBoxItem>Element 2</ComboBoxItem>
            <ComboBoxItem Visibility="Collapsed">Collapsed Element</ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

如果我禁用该元素,我仍然可以 select 按 C 键。有没有办法隐藏它而不删除它?

这对我来说确实像是一个错误!一个简单的替代方法是绑定到 ObservableCollection 并操纵 ObservableCollection 以完全不包含该项目。

这是我第二次尝试回答这个问题。第一个基于此处描述的方法: http://blog.elgaard.com/2009/09/03/wpf-making-combo-box-items-disabled-also-when-accessed-using-the-keyboard/ ,它不适用于问题中描述的用例。

Google 的进一步研究证实这是一个相当古老的错误:

https://social.msdn.microsoft.com/Forums/vstudio/en-us/23b4b0e9-c33b-4353-80e8-5735051aa921/how-can-i-disable-comboboxitems-for-keyboard-input?forum=wpf

https://social.msdn.microsoft.com/Forums/vstudio/en-US/baa9d1ff-8afa-46c0-8981-9144622c0074/wpf-combobox-disable-items?forum=wpf

这些页面的最佳解决方案是一个非常丑陋的代码隐藏组合:

XAML:

<StackPanel>
    <ComboBox x:Name="myComboBox" SelectionChanged="myComboBox_SelectionChanged">
        <ComboBoxItem>Element 1</ComboBoxItem>
        <ComboBoxItem>Element 2</ComboBoxItem>
        <ComboBoxItem Visibility="Collapsed" IsEnabled="False">Collapsed Element</ComboBoxItem>
    </ComboBox>
</StackPanel>

代码隐藏:

private void myComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (this.myComboBox.SelectedItem == null) return;

    ComboBoxItem cbi = this.myComboBox.ItemContainerGenerator.ContainerFromItem(this.myComboBox.SelectedItem) as ComboBoxItem;

    if (cbi != null && cbi.IsEnabled == false)
    {
        if (e.RemovedItems.Count > 0)
        {
            this.myComboBox.SelectedItem = e.RemovedItems[0];
        }
        else
        {
            this.myComboBox.SelectedIndex = -1;
        }

        return;
    }
}

每当禁用的 ComboBoxItem 变为 SelectedItem 时,这会将 SelectedItem 重置为之前的选择。