One way of dealing with large comboboxes is filtering. Another technique is proposing only the most popular items in the default list, and provide a hyperlink to the full list:

If the hyperlink is clicked, the ComboBox is entirely populated, but by adding non-selectable items you can still make the distinction:

Here's the full code for the demo:
XAML
<Window x:Class="DockOfTheBay.SuggestionComboBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DockOfTheBay"
Title="Suggestion ComboBox"
Height="120" Width="300">
<StackPanel Orientation="Horizontal"
VerticalAlignment="Top"
Margin="10 10">
<TextBlock Text="Select: "
Padding="4 3"/>
<ComboBox
x:Name="SuggestionComboBox1"
Padding="4 3"
MinWidth="200"/>
</StackPanel>
</Window>
C#
namespace DockOfTheBay{ using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media;/// <summary>
/// Demonstration of using non-selectable items and hyperlinks in a
/// WPF ComboBox.
/// </summary>
public partial class SuggestionComboBoxSample : Window
{/// <summary>
/// The hyperlink displayed after the the ComboBox's Suggestions.
/// </summary>
private ComboBoxItem linkItem;
/// <summary>
/// Initializes a new instance of the SuggestionComboBoxSample class.
/// </summary>
public SuggestionComboBoxSample() {InitializeComponent();
// Add an item that looks like a titleComboBoxItem item = new ComboBoxItem();
item.Content = "Most Frequent"; item.IsEnabled = false; item.Background = Brushes.Blue; item.Foreground = Brushes.White;SuggestionComboBox1.Items.Add(item);
// Add suggestionsforeach (var name in this.Suggestions())
{SuggestionComboBox1.Items.Add(name);
}
// Don't add content directly, like the following: // SuggestionComboBox1.Items.Add(new Separator()); // It will not display properly when databinding is used.item = new ComboBoxItem();
item.Content = new Separator();
SuggestionComboBox1.Items.Add(item);
Hyperlink link = new Hyperlink();
// 'RequestNavigate' is not fired, so use 'Click' instead link.Click += this.Link_Click;link.Inlines.Add(new Run("Show Everything"));
item = new ComboBoxItem();
item.Content = link;
this.linkItem = item;SuggestionComboBox1.Items.Add(item);
}
/// <summary>
/// Fetches the remaining items, and adds them to the ComboBox.
/// </summary>
/// <param name="sender">The HyperLink.</param>
/// <param name="e">The Event Arg.</param>
private void Link_Click(object sender, RoutedEventArgs e)
{ // Remove Hyperlink SuggestionComboBox1.Items.Remove(this.linkItem); // Add an item that looks like a titleComboBoxItem item = new ComboBoxItem();
item.Content = "The Rest"; item.IsEnabled = false; item.Background = Brushes.Blue; item.Foreground = Brushes.White;SuggestionComboBox1.Items.Add(item);
// Add suggestionsforeach (var name in this.Rest())
{SuggestionComboBox1.Items.Add(name);
}
}
/// <summary>
/// The Suggested Items.
/// </summary>
/// <returns>A list of Suggestions.</returns>
private List<string> Suggestions()
{List<string> names = new List<string>();
names.Add("WPF rocks"); names.Add("WCF rocks"); names.Add("XAML is fun"); return names;}
/// <summary>
/// The non-Suggested Items.
/// </summary>
/// <returns>A list of non-Suggestions.</returns>
private List<string> Rest()
{List<string> names = new List<string>();
names.Add("WPF rules"); names.Add("WCF rules"); names.Add("WinForms not"); return names;}
}
}
Here's how the control looks like in a real-life application for cancer registration. It presents a list of the most probable histologic diagnoses, based on key words in the tumor location:

This is not the correct method of doing this. The CollectionViewSource has built in grouping functionality that should be used instead.
ReplyDelete