我们正在尝试创建一个 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" });
}
}
}