我们正在尝试创建一个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" });
}
}
}
答案 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>
如果您正在绑定,则需要使用触发器。