title: How can you disallow an item in a ListBox from being selected?
body: <p>We're trying to create a ListBox which has a few items inside that the user cannot select.  Think the group headings in a grouped listbox, except these are independent items (i.e. no indented children.)  We just want to display a message in the list.</p>
  
  <p>Here's a mock-up of what we currently display if there are 'Foo' items...</p>
  
  <pre><code>Foo 1
  Foo 2
  Foo 3
  --------------   &lt;-- This is of type 'Separator' so it's styled as not-selectable by default.
  Add new Foo...
  Manage Foos...
  </code></pre>
  
  <p>...and if there aren't any Foo items, we display this...</p>
  
  <pre><code>[No Foo Items]   &lt;-- This one should not be selectable, the same as a separator
  --------------   &lt;-- This is of type 'Separator' so it's styled as not-selectable by default.
  Add new Foo...
  Manage Foos...
  </code></pre>
  
  <p>Now again, we already have the code that properly handles what's displayed (see below).  We're wondering what's the proper way to disable that entry from being able to be selected.</p>
  
  <p>What we don't know is how to style that ListBoxItem so the selection skips right over it, nor can the user click on it.</p>
  
  <h2>Code</h2>
  
  <p>Someone asked me to see my code, so here it is.  Not really relevant to the question, but should show people how I did this.</p>
  
  <p>Note: We template the <code>string.Empty</code> in the XAML to show the localized 'No xxx Items' message.  <code>string.Empty</code> is just a placeholder that we can target.</p>
  
  <p>Note 2: FauxData is a simple library of items and collections used for testing so I don't have to constantly create them from scratch.  SimpleItemCollection for instance creates ten SimpleItem objects in the constructor, pre-populated with things like Name, Description, IsSelected, etc. all fully supporting INotifyPropertyChanged and collection change notifications.  I have the same thing with HierarchicalItemsCollection which adds Parent, Children and IsExpanded, etc. It saves a LOT of work when testing code and controls!</p>
  
  <p>Finally, this is from a simple test, or 'playground' app. As such, it's not supposed to represent the best way to do things, just to show a concept. Yes, it can be cleaned up a lot, but you get the general idea.</p>
  
  <p>Anyway, on to the code...</p>
  
  <pre><code>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&lt;object&gt;();
  
              itemsCollection.CollectionChanged += (s,e) =&gt; {
  
                  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);   // &lt;-- Pops a dialog to enter a new item
              cc.Add(ApplicationCommands.Open);  // &lt;-- 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" });
          }
  
      }
  
  }
  </code></pre>