2

我们正在尝试创建一个 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 的样式,以便选择直接跳过它,用户也不能点击它。

代码

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

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

注意 2:FauxData 是一个用于测试的简单项目和集合库,因此我不必经常从头开始创建它们。例如,SimpleItemCollection 在构造函数中创建了十个 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" });
        }

    }

}
4

3 回答 3

3

由于Focusable="false"不涵盖所有选项(例如单击并拖动选择),我建议改为设置IsEnabledfalse

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

于 2012-09-26T19:27:45.093 回答
1

哇!那很简单!在ListBoxItem你想跳过的地方,你只需设置FocusableFalse

完成并完成!

于 2012-09-26T18:35:17.233 回答
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>

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

于 2012-09-26T19:25:03.223 回答