Skip to content

Commit cd9a44e

Browse files
committed
Merge branch 'develop'
2 parents d4e1e94 + c08bae1 commit cd9a44e

1 file changed

Lines changed: 137 additions & 1 deletion

File tree

README.md

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<p align="center">
88
<a href="#-getting-started">Getting Started</a> ·
99
<a href="#-column-types">Columns</a> ·
10+
<a href="#-action-button-columns">Action Buttons</a> ·
1011
<a href="#-sorting--filtering">Sorting & Filtering</a> ·
1112
<a href="#-grouping">Grouping</a> ·
1213
<a href="#-editing">Editing</a> ·
@@ -35,6 +36,7 @@ Every visual element — cells, headers, editors, scrollbars, popups — is rend
3536
- [Features at a Glance](#-features-at-a-glance)
3637
- [Getting Started](#-getting-started)
3738
- [Column Types](#-column-types)
39+
- [Action Button Columns](#-action-button-columns)
3840
- [Column Sizing](#-column-sizing)
3941
- [Frozen Columns & Rows](#-frozen-columns--rows)
4042
- [Sorting & Filtering](#-sorting--filtering)
@@ -68,14 +70,15 @@ Every visual element — cells, headers, editors, scrollbars, popups — is rend
6870
| **Rendering** | 100% SkiaSharp canvas, zero native controls, 60 fps |
6971
| **Virtual scrolling** | Only visible rows/columns rendered — tested with 100K+ rows |
7072
| **Column types** | Text, Numeric, Boolean, Date, ComboBox, Picker, ProgressBar, Image, Template |
73+
| **Action buttons** | Pill-button columns with `ICommand` / callback support; activate on first tap |
7174
| **Column sizing** | Fixed, Star (proportional), Auto (content-sized) |
7275
| **Frozen columns** | Pin columns to left or right edge |
7376
| **Frozen rows** | Pin top N rows to viewport |
7477
| **Sorting** | Tap header to cycle asc/desc/none; multi-column |
7578
| **Filtering** | Excel-style popup with search, value checklist, and sort controls |
7679
| **Grouping** | Drag-and-drop group panel, expandable groups, nested groups |
7780
| **Summaries** | Table-level and per-group aggregates (Sum, Avg, Count, Min, Max) |
78-
| **Editing** | Configurable triggers (tap, double-tap, long-press, F2, typing) |
81+
| **Editing** | Configurable triggers (tap, double-tap, long-press, F2, typing); per-column override |
7982
| **Selection** | Single / Multiple / Extended modes; Row or Cell unit |
8083
| **Keyboard nav** | Arrows, Tab/Shift+Tab, Enter, Home/End, Page Up/Down |
8184
| **Row drag & drop** | Handle column or full-row drag reorder |
@@ -190,6 +193,104 @@ Each column is a `DataGridColumn` with a `ColumnType` that controls both the rea
190193

191194
---
192195

196+
## 🖱️ Action Button Columns
197+
198+
Action button columns render a row of clickable pill-buttons directly inside every cell. Any number of buttons can be declared; they are distributed with equal widths across the cell area. Buttons support both `ICommand` (for MVVM data-binding) and an `Action` callback (for code-behind).
199+
200+
Action buttons use the **Template** column type with `ActionButtonsCellRenderer` as the `CustomCellRenderer`. The renderer also implements `ICellEditorProvider`, so no separate `CustomEditorFactory` is required — the same button definitions handle both display and interaction.
201+
202+
> **Tip:** Set the column's `EditTriggers="SingleTap"` so buttons respond on the first touch, even when the grid's default trigger is `DoubleTap`. See [Per-column edit trigger override](#per-column-edit-trigger-override).
203+
204+
### XAML declaration (MVVM)
205+
206+
Set `PropertyName=""` so the full row item is passed as the value to both the renderer and the editor.
207+
`MauiActionButtonDefinition` is a `BindableObject` that supports `{Binding}` on every property, including `Command`.
208+
209+
```xml
210+
xmlns:dg="clr-namespace:KumikoUI.Maui;assembly=KumikoUI.Maui"
211+
xmlns:render="clr-namespace:KumikoUI.Core.Rendering;assembly=KumikoUI.Core"
212+
213+
<dg:DataGridView x:Name="actionsGrid" ...>
214+
<dg:DataGridView.Columns>
215+
<core:DataGridColumn Header="Actions"
216+
PropertyName=""
217+
ColumnType="Template"
218+
Width="200"
219+
AllowSorting="False"
220+
AllowFiltering="False"
221+
AllowTabStop="False"
222+
EditTriggers="SingleTap">
223+
<core:DataGridColumn.CustomCellRenderer>
224+
<render:ActionButtonsCellRenderer>
225+
<render:ActionButtonsCellRenderer.Buttons>
226+
<dg:MauiActionButtonDefinition
227+
Label="Details"
228+
BackgroundColor="13,110,253"
229+
Command="{Binding Path=BindingContext.ViewDetailsCommand,
230+
Source={x:Reference actionsGrid}}" />
231+
<dg:MauiActionButtonDefinition
232+
Label="Delete"
233+
BackgroundColor="220,53,69"
234+
Command="{Binding Path=BindingContext.DeleteCommand,
235+
Source={x:Reference actionsGrid}}" />
236+
</render:ActionButtonsCellRenderer.Buttons>
237+
</render:ActionButtonsCellRenderer>
238+
</core:DataGridColumn.CustomCellRenderer>
239+
</core:DataGridColumn>
240+
</dg:DataGridView.Columns>
241+
</dg:DataGridView>
242+
```
243+
244+
> **Note:** `MauiActionButtonDefinition` is not in the visual tree, so it does **not** inherit `BindingContext` automatically. Use `Source={x:Reference …}` or `Source={RelativeSource …}` to point bindings at the correct source object.
245+
246+
### Code-behind factory
247+
248+
Use `ActionButtonDefinition` (in `KumikoUI.Core`) when you want a code-behind closure per row:
249+
250+
```csharp
251+
actionsColumn.CustomEditorFactory = (value, bounds) => new DrawnActionButtons
252+
{
253+
Bounds = bounds,
254+
RowItem = value,
255+
Buttons =
256+
[
257+
new ActionButtonDefinition
258+
{
259+
Label = "Edit",
260+
BackgroundColor = new GridColor(13, 110, 253),
261+
Command = vm.EditCommand // row item is CommandParameter by default
262+
},
263+
new ActionButtonDefinition
264+
{
265+
Label = "Delete",
266+
BackgroundColor = new GridColor(220, 53, 69),
267+
Action = () => vm.DeleteEmployee((Employee)value!)
268+
}
269+
]
270+
};
271+
```
272+
273+
### Button properties
274+
275+
| Property | Type | Description |
276+
|---|---|---|
277+
| `Label` | `string` | Text displayed on the button face |
278+
| `BackgroundColor` | `GridColor` | Pill background color (`R,G,B` string format in XAML) |
279+
| `TextColor` | `GridColor` | Label text color (default: white) |
280+
| `Command` | `ICommand?` | Executed on tap; row item is the default `CommandParameter` |
281+
| `CommandParameter` | `object?` | Explicit command parameter; overrides the row item default |
282+
| `Action` | `Action?` | Code-behind callback; executed in addition to `Command` if both are set |
283+
284+
Layout properties on `DrawnActionButtons` / `ActionButtonsCellRenderer`:
285+
286+
| Property | Default | Description |
287+
|---|---|---|
288+
| `CornerRadius` | `5f` | Button pill corner radius (pixels) |
289+
| `ButtonSpacing` | `6f` | Horizontal gap between buttons (pixels) |
290+
| `CellPadding` | `4f` | Inset from all four cell edges (pixels) |
291+
292+
---
293+
193294
## 📐 Column Sizing
194295

195296
Columns support three sizing modes controlled by the `SizeMode` property.
@@ -344,6 +445,40 @@ Configure which gestures or keys open the inline editor:
344445

345446
Triggers are flags — combine freely: `"DoubleTap,F2Key,Typing"`.
346447

448+
### Per-column edit trigger override
449+
450+
Each column can override the grid-level `EditTriggers` independently via its own `EditTriggers` property. When set, that column uses its own trigger flags; when `null` (the default), the column inherits the grid-level setting.
451+
452+
```xml
453+
<dg:DataGridView EditTriggers="DoubleTap, F2Key, Typing">
454+
<dg:DataGridView.Columns>
455+
456+
<!-- Most accessible: single-tap, F2, or typing to edit -->
457+
<core:DataGridColumn Header="Name" PropertyName="Name"
458+
EditTriggers="SingleTap, F2Key, Typing" />
459+
460+
<!-- ComboBox: double-tap or F2 only (no accidental typing edits) -->
461+
<core:DataGridColumn Header="Department" PropertyName="Department"
462+
ColumnType="ComboBox"
463+
EditorItemsString="Engineering,Marketing,Finance,HR"
464+
EditTriggers="DoubleTap, F2Key" />
465+
466+
<!-- Salary: keyboard-only — protects financial data from pointer gestures -->
467+
<core:DataGridColumn Header="Salary" PropertyName="Salary"
468+
ColumnType="Numeric" Format="C0"
469+
EditTriggers="F2Key" />
470+
471+
<!-- Action buttons always activate on first tap -->
472+
<core:DataGridColumn Header="Actions" PropertyName=""
473+
ColumnType="Template"
474+
EditTriggers="SingleTap" />
475+
476+
</dg:DataGridView.Columns>
477+
</dg:DataGridView>
478+
```
479+
480+
Set `EditTriggers="None"` to suppress all gesture/keyboard triggers for a column without making it fully read-only via `IsReadOnly`.
481+
347482
### Edit text selection
348483

349484
```xml
@@ -627,6 +762,7 @@ See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for an in-depth contributor gui
627762
|---|---|
628763
| **All Components** | Every column type, frozen columns, frozen rows, edit triggers, selection modes, drag & drop, summaries, theme toggle |
629764
| **Grouping & Filtering** | Interactive group panel, nested groups, filter popups, group summaries |
765+
| **MVVM + Column EditTriggers** | Action button columns with MVVM commands; per-column `EditTriggers` overrides across all trigger types |
630766
| **Large Data** | 100K-row stress test with virtual scrolling performance metrics |
631767
| **Theming** | Live Light / Dark / HighContrast switching, custom color picker |
632768

0 commit comments

Comments
 (0)