BeepSelect
Modern, theme-aware selection control with advanced filtering, multi-selection, and customizable item templates
📋 Table of Contents
Overview
BeepSelect provides a modern, enhanced selection interface that goes beyond traditional comboboxes and listboxes. It offers advanced filtering, multi-selection capabilities, custom item templates, and seamless integration with data sources for sophisticated user selection scenarios.
Built on the BeepControl foundation, BeepSelect features intelligent search functionality, grouped items support, custom rendering, virtualization for large datasets, theme integration, and accessibility features. Perfect for user management interfaces, product catalogs, configuration panels, and any application requiring advanced selection capabilities.
Key Features
🔍 Smart Filtering
Built-in search with fuzzy matching and custom filter functions
✅ Multi-Selection
Support for single and multi-selection modes with chips display
🎨 Custom Templates
Flexible item templating with rich content support
📊 Data Binding
Seamless integration with data sources and complex objects
🏷️ Grouping Support
Organize items into collapsible groups with headers
⚡ Virtualization
Efficient rendering for large datasets with lazy loading
Visual Preview
Single Selection Mode
Single selection with search, grouping, and rich item templates
Multi-Selection Mode
Multi-selection with chips display and inline editing
Basic Usage
Simple Selection Control
// Create and configure a BeepSelect
var selectControl = new BeepSelect();
selectControl.Size = new Size(250, 35);
selectControl.Placeholder = "Select an option...";
// Add simple string items
selectControl.Items.AddRange(new[] {
"Option 1",
"Option 2",
"Option 3",
"Option 4"
});
// Handle selection changes
selectControl.SelectionChanged += (s, e) =>
{
var selectedItem = selectControl.SelectedItem;
MessageBox.Show($"Selected: {selectedItem}");
};
// Add to form
this.Controls.Add(selectControl);
Data-Bound Selection with Objects
// Define data model
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public string Position { get; set; }
public bool IsManager { get; set; }
}
// Create and configure BeepSelect
var employeeSelect = new BeepSelect
{
Size = new Size(300, 40),
Placeholder = "Select employee...",
DisplayMember = "Name",
ValueMember = "Id",
GroupMember = "Department", // Group by department
EnableSearch = true,
MultiSelect = false
};
// Bind data
var employees = GetEmployees(); // Your data source
employeeSelect.DataSource = employees;
// Configure custom item template
employeeSelect.ItemTemplate = (item) =>
{
var emp = item as Employee;
return $"{emp.Name} - {emp.Position}" + (emp.IsManager ? " (Manager)" : "");
};
// Handle selection
employeeSelect.SelectionChanged += (s, e) =>
{
var selectedEmployee = employeeSelect.SelectedItem as Employee;
if (selectedEmployee != null)
{
ShowEmployeeDetails(selectedEmployee);
}
};
Properties
Core Properties
| Property | Type | Default | Description |
|---|---|---|---|
Items |
IList | Empty | Collection of items to display |
SelectedItem |
object | null | Currently selected item (single selection) |
SelectedItems |
IList | Empty | Selected items collection (multi-selection) |
MultiSelect |
bool | false | Enable multi-selection mode |
Data Binding Properties
| Property | Type | Default | Description |
|---|---|---|---|
DataSource |
object | null | Data source for binding |
DisplayMember |
string | "" | Property name for display text |
ValueMember |
string | "" | Property name for item value |
GroupMember |
string | "" | Property name for grouping items |
UI Properties
| Property | Type | Default | Description |
|---|---|---|---|
Placeholder |
string | "" | Placeholder text when no selection |
EnableSearch |
bool | true | Enable search/filter functionality |
SearchPlaceholder |
string | "Search..." | Placeholder text for search box |
MaxDropdownHeight |
int | 300 | Maximum height of dropdown panel |
Events
| Event | Event Args | Description |
|---|---|---|
SelectionChanged |
SelectionChangedEventArgs | Fired when selection changes |
SearchTextChanged |
EventArgs | Fired when search text changes |
ItemRendering |
ItemRenderingEventArgs | Fired when custom item rendering is needed |
DropdownOpening |
CancelEventArgs | Fired before dropdown opens (cancellable) |
Examples
Advanced Multi-Select with Custom Filtering
public class SkillsSelector : UserControl
{
private BeepSelect skillsSelect;
private List availableSkills;
public List SelectedSkills =>
skillsSelect.SelectedItems.Cast().ToList();
public SkillsSelector()
{
InitializeSkillsSelector();
LoadSkills();
}
private void InitializeSkillsSelector()
{
skillsSelect = new BeepSelect
{
Dock = DockStyle.Fill,
MultiSelect = true,
Placeholder = "Add skills...",
DisplayMember = "Name",
ValueMember = "Id",
GroupMember = "Category",
EnableSearch = true,
SearchPlaceholder = "Search skills...",
MaxDropdownHeight = 400
};
// Custom search filter
skillsSelect.SearchFilter = (item, searchText) =>
{
var skill = item as Skill;
return skill.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase) ||
skill.Category.Contains(searchText, StringComparison.OrdinalIgnoreCase) ||
skill.Keywords.Any(k => k.Contains(searchText, StringComparison.OrdinalIgnoreCase));
};
// Custom item template with badges
skillsSelect.ItemTemplate = (item) =>
{
var skill = item as Skill;
var template = $"{skill.Name}";
if (skill.IsInDemand)
template += " 🔥";
if (skill.IsCertified)
template += " ✓";
return template;
};
// Handle selection changes
skillsSelect.SelectionChanged += OnSkillsSelectionChanged;
this.Controls.Add(skillsSelect);
}
private void LoadSkills()
{
availableSkills = new List
{
new Skill { Id = 1, Name = "C#", Category = "Programming", IsInDemand = true, IsCertified = true, Keywords = new[] { "dotnet", "csharp", "programming" } },
new Skill { Id = 2, Name = "JavaScript", Category = "Programming", IsInDemand = true, Keywords = new[] { "js", "frontend", "web" } },
new Skill { Id = 3, Name = "Python", Category = "Programming", IsInDemand = true, Keywords = new[] { "data science", "ml", "ai" } },
new Skill { Id = 4, Name = "SQL", Category = "Database", IsInDemand = true, IsCertified = true, Keywords = new[] { "database", "query" } },
new Skill { Id = 5, Name = "Docker", Category = "DevOps", IsInDemand = true, Keywords = new[] { "containers", "deployment" } },
new Skill { Id = 6, Name = "Kubernetes", Category = "DevOps", Keywords = new[] { "orchestration", "containers" } },
new Skill { Id = 7, Name = "Project Management", Category = "Soft Skills", Keywords = new[] { "planning", "coordination" } },
new Skill { Id = 8, Name = "Communication", Category = "Soft Skills", Keywords = new[] { "presentation", "teamwork" } }
};
skillsSelect.DataSource = availableSkills;
}
private void OnSkillsSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedSkills = SelectedSkills;
// Update UI or notify parent
OnSelectedSkillsChanged(selectedSkills);
// Show recommendation based on selected skills
ShowSkillRecommendations(selectedSkills);
}
private void ShowSkillRecommendations(List selectedSkills)
{
var recommendations = GetSkillRecommendations(selectedSkills);
if (recommendations.Any())
{
var message = $"Based on your selected skills, you might also be interested in: {string.Join(", ", recommendations.Select(r => r.Name))}";
// Show tooltip or notification
ToolTip.Show(message, this, 3000);
}
}
private List GetSkillRecommendations(List selectedSkills)
{
// Simple recommendation logic
var selectedCategories = selectedSkills.Select(s => s.Category).Distinct();
return availableSkills
.Where(s => !selectedSkills.Contains(s) &&
selectedCategories.Contains(s.Category) &&
s.IsInDemand)
.Take(3)
.ToList();
}
public event Action> SelectedSkillsChanged;
protected virtual void OnSelectedSkillsChanged(List skills) =>
SelectedSkillsChanged?.Invoke(skills);
}
public class Skill
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public bool IsInDemand { get; set; }
public bool IsCertified { get; set; }
public string[] Keywords { get; set; } = Array.Empty();
}
Theming
BeepSelect provides comprehensive theming support with full integration into the Beep Controls theming system:
Theme Application
var selectControl = new BeepSelect
{
Theme = "ModernDark",
UseThemeColors = true
}
// Theme automatically applies:
// - ControlBackColor: Input field background
// - ControlForeColor: Text colors
// - BorderColor: Input and dropdown borders
// - DropdownBackColor: Dropdown panel background
// - SelectionColor: Selected item highlighting
// - ChipColors: Multi-select chip styling
Select-Specific Theming
- Chip styling - Multi-select chip colors and hover effects
- Dropdown theming - Panel backgrounds and border colors
- Search integration - Search box styling within theme
- Group headers - Category header styling and colors
Best Practices
🎯 User Experience
- Clear placeholders: Use descriptive placeholder text to guide users
- Logical grouping: Group related items for easier navigation
- Search optimization: Implement meaningful search across multiple properties
- Visual feedback: Provide clear visual feedback for selections
🔧 Implementation
- Data binding: Use proper data binding for dynamic content
- Performance: Implement virtualization for large datasets
- Validation: Validate selections and provide appropriate feedback
- Accessibility: Ensure keyboard navigation and screen reader support
📊 Data Handling
- Object equality: Implement proper equality comparison for custom objects
- Null handling: Handle null values gracefully in data sources
- State management: Properly manage selection state across UI updates
Use custom item templates to provide rich, informative displays that help users make better selections.
Implement intelligent search that includes synonyms, abbreviations, and related terms for better user experience.
For large datasets (>1000 items), enable virtualization and consider implementing server-side filtering.