Siticone GroupChipPanel
The SiticoneGroupChipPanel is a specialized container control designed to orchestrate collections of
SiticoneGroupChip elements.
Built upon the standard FlowLayoutPanel architecture, it provides automatic flow layout while adding sophisticated logic for
group-based single selection, multi-selection, and user-driven drag-and-drop reordering.
Selection Logic & Groups
The panel acts as a controller for the chips inside it. It can enforce logic where certain chips behave like Radio Buttons (Single Select) while others behave like Checkboxes (Multi Select), all within the same container.
| Property | Type | Description & Usage Example |
|---|---|---|
ChipSelectionMode |
ChipSelectionMode |
panel.ChipSelectionMode = ChipSelectionMode.Multiple;
Defines the global selection behavior:
|
AllowGroupSelection |
bool |
panel.AllowGroupSelection = true;
Advanced Logic: When enabled (and mode is Multiple), the panel enforces single-selection per unique Group name.
Chips with no group name (null/empty) remain multi-selectable.
Use Case: Mixing "Size" (Single Select) and "Toppings" (Multi Select) in one menu. |
EnableChipSelection |
bool |
panel.EnableChipSelection = false;
Master switch for interactivity. If set to false, all chips in the panel become read-only (visual only) and cannot be toggled by the user.
|
Drag & Drop Reordering
Integrated functionality allowing users to visually rearrange items. The panel automatically handles index updates and layout refreshing.
| Property | Type | Description & Usage Example |
|---|---|---|
EnableDragAndDrop |
bool |
panel.EnableDragAndDrop = true;
If true, users can click and drag chips to new positions. The underlying control collection order is updated to reflect the visual order.
|
DragCursor |
Cursor |
panel.DragCursor = Cursors.SizeAll;
Sets the mouse cursor displayed while a chip is being dragged. Default is Cursors.Hand.
|
Layout & Scrolling
Inherits robust layout capabilities from FlowLayoutPanel.
| Property | Type | Description & Usage Example |
|---|---|---|
FlowDirection |
FlowDirection |
panel.FlowDirection = FlowDirection.LeftToRight;
Determines the direction chips are arranged (e.g., LeftToRight, TopDown).
|
WrapContents |
bool |
panel.WrapContents = true;
If true, chips move to the next row/column when they run out of space. If false, the container simply extends.
|
AutoScroll |
bool | panel.AutoScroll = true; Enables scrollbars automatically when the chips exceed the visible area of the panel. |
Management Methods
Helper methods to interact with chips programmatically, avoiding manual iteration of the Controls collection.
// Adds a new chip to the panel and automatically wires up selection and group logic.
siticoneGroupChipPanel1.AddChip(newChip);
// Removes a specific chip and unhooks its event handlers to prevent memory leaks.
siticoneGroupChipPanel1.RemoveChip(existingChip);
// Returns a list of all chips where IsSelected is currently true.
List<SiticoneGroupChip> selected = siticoneGroupChipPanel1.GetSelectedChips();
// Returns all chips belonging to a specific group string (case-insensitive).
List<SiticoneGroupChip> sizeChips = siticoneGroupChipPanel1.GetChipsByGroup("Size");
// Returns a list of all unique Group names currently present in the panel.
List<string> groups = siticoneGroupChipPanel1.GetAllGroups();
Events
// Occurs when ANY chip's selection state changes (Selected or Deselected)
panel.SelectedChipsChanged += (sender, e) =>
{
Console.WriteLine($"Total Selected: {e.SelectedChips.Count}");
foreach(var chip in e.SelectedChips)
{
// e.SelectedChips contains the updated list of active items
Console.WriteLine($"Active: {chip.Text} [Group: {chip.Group}]");
}
};
// Occurs when a chip is added via AddChip() or the Designer
panel.ChipAdded += (sender, e) => Log("Added: " + e.Chip.Text);
// Occurs when a chip is removed via RemoveChip()
panel.ChipRemoved += (sender, e) => Log("Removed: " + e.Chip.Text);
Detailed Usage Examples
Example 1: Mixed "Radio & Checkbox" Logic
This example creates a "Pizza Configurator". Users must pick exactly one Size (Radio behavior) but can pick multiple Toppings (Checkbox behavior).
private void InitializePizzaMenu()
{
// 1. Configure Panel for Multiple Selections generally
chipPanel.ChipSelectionMode = ChipSelectionMode.Multiple;
// 2. Enforce Single-Selection for named Groups
chipPanel.AllowGroupSelection = true;
// --- Create "Size" Group (Radio Behavior) ---
// Because they share the group name "Size", only ONE can be active.
AddChip("Small", "Size");
AddChip("Medium", "Size");
AddChip("Large", "Size");
// --- Create "Toppings" (Checkbox Behavior) ---
// By leaving the group empty (""), these remain purely multi-select.
AddChip("Extra Cheese", "");
AddChip("Pepperoni", "");
AddChip("Mushrooms", "");
// 4. Set Default Selection
var mediumChip = chipPanel.GetChipsByGroup("Size")
.FirstOrDefault(c => c.Text == "Medium");
if(mediumChip != null) mediumChip.IsSelected = true;
}
private void AddChip(string text, string group)
{
var chip = new SiticoneGroupChip();
chip.Text = text;
chip.Group = group;
chip.RoundedCorners = true;
chip.FillColor = Color.WhiteSmoke;
chipPanel.AddChip(chip);
}
Example 2: Processing Data from the Panel
How to retrieve and process the user's choices when a form is submitted.
private void BtnSubmit_Click(object sender, EventArgs e)
{
// 1. Retrieve all active chips
var selectedChips = chipPanel.GetSelectedChips();
if (selectedChips.Count == 0)
{
MessageBox.Show("Please select at least one option.");
return;
}
// 2. Extract Data
string selectedSize = "None";
List<string> toppings = new List<string>();
foreach (var chip in selectedChips)
{
if (chip.Group == "Size")
selectedSize = chip.Text;
else
toppings.Add(chip.Text);
}
// 3. Process Order
Console.WriteLine($"Size: {selectedSize}");
Console.WriteLine($"Toppings: {string.Join(", ", toppings)}");
}
Example 3: Favorites List with Drag & Drop
Allowing users to create a ranked list of items by dragging them into order.
private void SetupFavoritesPanel()
{
// 1. Enable Dragging
chipPanel.EnableDragAndDrop = true;
chipPanel.DragCursor = Cursors.SizeAll; // Visual cue for moving
// 2. Populate Items
string[] modules = { "Dashboard", "Reports", "Users", "Settings" };
foreach (var item in modules)
{
chipPanel.AddChip(new SiticoneGroupChip { Text = item });
}
}
// Method to save the new order after user rearranges items
public List<string> GetVisualOrder()
{
var orderedList = new List<string>();
// The Controls collection automatically reflects the visual order after a drag-drop
foreach (SiticoneGroupChip chip in chipPanel.Controls)
{
orderedList.Add(chip.Text);
}
return orderedList;
}