如何禁止选择ListBox中的项目?

时间:2012-09-26 18:29:26

标签: wpf listbox focus selection

我们正在尝试创建一个ListBox,其中包含一些用户无法选择的项目。将组标题视为分组列表框,除了这些是独立项目(即没有缩进的子项)。我们只想在列表中显示一条消息。

如果有'Foo'项目,这里是我们当前显示的模型...

Foo 1
Foo 2
Foo 3
--------------   <-- This is of type 'Separator' so it's styled as not-selectable by default.
Add new Foo...
Manage Foos...

...如果没有任何Foo项目,我们会显示...

[No Foo Items]   <-- This one should not be selectable, the same as a separator
--------------   <-- This is of type 'Separator' so it's styled as not-selectable by default.
Add new Foo...
Manage Foos...

现在我们已经有了正确处理显示内容的代码(见下文)。我们想知道什么是禁止该条目被选中的正确方法。

我们不知道的是如何设置ListBoxItem的样式,以便选择跳过它,用户也不能点击它。

代码

有人让我看到我的代码,所以在这里。与问题不太相关,但应向人们展示我是如何做到的。

注意:我们在XAML中模拟string.Empty以显示本地化的“No xxx Items”消息。 string.Empty只是我们可以定位的占位符。

注2:FauxData是一个简单的项目和集合库,用于测试,因此我不必从头开始不断创建它们。例如,SimpleItemCollection在构造函数中创建了10个SimpleItem对象,预先填充了Name,Description,IsSelected等所有对象,它们全部支持INotifyPropertyChanged和集合更改通知。我对HierarchicalItemsCollection做了同样的事情,它添加了Parent,Children和IsExpanded等。它在测试代码和控件时节省了大量的工作!

最后,这是来自一个简单的测试,或“游乐场”应用程序。因此,它不应该代表最好的做事方式,只是为了展示一个概念。是的,它可以清理很多,但你会得到一般的想法。

无论如何,代码......

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using FauxData;

namespace Playground.ListTest
{
    [LaunchEntry("List Test")]
    public partial class Main : Window
    {
        SimpleItemCollection itemsCollection = new SimpleItemCollection(); // Default constructor creates 10 items

        public Main()
        {
            InitializeComponent();
            MainListBox.ItemsSource = CreateCompositeCollection();
        }

        private CompositeCollection CreateCompositeCollection()
        {
            var EmptyHolder = new ObservableCollection<object>();

            itemsCollection.CollectionChanged += (s,e) => {

                if(itemsCollection.Count != 0)
                    EmptyHolder.Clear();
                else if(EmptyHolder.Count == 0)
                    EmptyHolder.Add(string.Empty);

            };

            var cc = new CompositeCollection();

            cc.Add(new CollectionContainer(){ Collection = itemsCollection });
            cc.Add(new CollectionContainer(){ Collection = EmptyHolder });
            cc.Add(new Separator());
            cc.Add(ApplicationCommands.New);   // <-- Pops a dialog to enter a new item
            cc.Add(ApplicationCommands.Open);  // <-- Shows an item management window

            return cc;

        }

        private void Test_Click(object sender, RoutedEventArgs e)
        {
            if(itemsCollection.Count != 0)
                itemsCollection.Clear();
            else
                itemsCollection.Add(new SimpleItem(){Name = "New item" });
        }

    }

}

3 个答案:

答案 0 :(得分:3)

由于Focusable="false"未涵盖所有选项(例如点击并拖动选择),我建议您将IsEnabled设置为false

(灰色文本是ListBoxItem样式/模板的问题,所以如果您不喜欢它,则需要覆盖它)

答案 1 :(得分:1)

哇!那很简单!在您要跳过的ListBoxItem上,您只需将Focusable设置为False

完成并完成!

答案 2 :(得分:1)

如果你不希望它变灰,那么IsHitTestVisible似乎可以实现这一点。

    <ListBox SelectionMode="Multiple">
        <ListBoxItem IsEnabled="False">HEsder</ListBoxItem>
        <ListBoxItem IsEnabled="True">1</ListBoxItem>
        <ListBoxItem IsHitTestVisible="False">-----</ListBoxItem>
        <ListBoxItem IsEnabled="True">2</ListBoxItem>
    </ListBox>

如果您正在绑定,则需要使用触发器。