SKILLS/shiny-tableview/SKILL.md
Generate settings-style TableView pages and cells for .NET MAUI using Shiny.Maui.TableView - a pure MAUI implementation with cascading styles, 14 cell types, sections, drag-sort, and full MVVM support
npx skillsauth add shinyorg/tableview shiny-tableviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an expert in Shiny.Maui.TableView, a pure .NET MAUI settings-style TableView control with 14 cell types, cascading styles, sections, drag-sort reordering, and full MVVM/binding support.
Invoke this skill when the user wants to:
Repository: https://github.com/shinyorg/tableview
Namespace: Shiny.Maui.TableView
XAML Namespace: http://shiny.net/maui/tableview (prefix: tv)
Shiny.Maui.TableView is a pure .NET MAUI implementation inspired by AiForms.Maui.SettingsView. Unlike AiForms which uses native platform renderers (UITableView on iOS, RecyclerView on Android), this library uses only standard MAUI layouts and views with zero platform-specific code.
dotnet add package Shiny.Maui.TableView
using Shiny.Maui.TableView;
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseShinyTableView();
xmlns:tv="http://shiny.net/maui/tableview"
The control hierarchy is:
tv:TableView (ContentView > ScrollView > VerticalStackLayout)
tv:TableRoot
tv:TableSection (Title, FooterText, cells)
tv:LabelCell / tv:SwitchCell / tv:CommandCell / etc.
Style cascade: TableView globals -> Section overrides -> Cell overrides. All properties are BindableProperty with full MVVM support.
Displays title with optional value text on the right.
<tv:LabelCell Title="Version" ValueText="1.0.0" Description="Latest release" />
| Property | Type | Default | Description |
|---|---|---|---|
| ValueText | string | "" | Right-side text |
| ValueTextColor | Color? | null | Value color |
| ValueTextFontSize | double | -1 | Value font size |
| ValueTextFontFamily | string? | null | Value font family |
| ValueTextFontAttributes | FontAttributes? | null | Value styling |
Toggle switch.
<tv:SwitchCell Title="Wi-Fi" On="{Binding WifiEnabled, Mode=TwoWay}" OnColor="#34C759" />
| Property | Type | Default |
|---|---|---|
| On | bool | false |
| OnColor | Color? | null |
Native checkbox control.
<tv:CheckboxCell Title="Accept Terms" Checked="{Binding Accepted, Mode=TwoWay}" AccentColor="Green" />
| Property | Type | Default |
|---|---|---|
| Checked | bool | false |
| AccentColor | Color? | null |
Checkmark toggle (no native checkbox, just a checkmark character).
<tv:SimpleCheckCell Title="Option A" Checked="{Binding OptionA, Mode=TwoWay}" />
| Property | Type | Default |
|---|---|---|
| Checked | bool | false |
| Value | object? | null |
| AccentColor | Color? | null |
Radio button selection. Use RadioCell.SelectedValue attached property on the section.
<tv:TableSection Title="Theme" tv:RadioCell.SelectedValue="{Binding SelectedTheme, Mode=TwoWay}">
<tv:RadioCell Title="Light" Value="Light" />
<tv:RadioCell Title="Dark" Value="Dark" />
<tv:RadioCell Title="System" Value="System" />
</tv:TableSection>
| Property | Type | Default |
|---|---|---|
| Value | object? | null |
| AccentColor | Color? | null |
Tappable cell with disclosure arrow. Inherits from LabelCell.
<tv:CommandCell Title="About" ValueText="Learn more"
Command="{Binding AboutCommand}"
KeepSelectedUntilBack="True" />
| Property | Type | Default |
|---|---|---|
| Command | ICommand? | null |
| CommandParameter | object? | null |
| ShowArrow | bool | true |
| KeepSelectedUntilBack | bool | false |
Full-width button-style cell.
<tv:ButtonCell Title="Sign Out" Command="{Binding SignOutCommand}" ButtonTextColor="Red" />
| Property | Type | Default |
|---|---|---|
| Command | ICommand? | null |
| CommandParameter | object? | null |
| ButtonTextColor | Color? | null |
| TitleAlignment | TextAlignment | Center |
Inline text input.
<tv:EntryCell Title="Email" ValueText="{Binding Email, Mode=TwoWay}"
Placeholder="[email protected]" Keyboard="Email" />
| Property | Type | Default |
|---|---|---|
| ValueText | string | "" |
| Placeholder | string | "" |
| PlaceholderColor | Color? | null |
| Keyboard | Keyboard | Default |
| IsPassword | bool | false |
| MaxLength | int | -1 |
| TextAlignment | TextAlignment | End |
| CompletedCommand | ICommand? | null |
| ValueTextColor | Color? | null |
Opens native date picker dialog on tap.
<tv:DatePickerCell Title="Birthday" Date="{Binding BirthDate, Mode=TwoWay}" Format="D" />
| Property | Type | Default |
|---|---|---|
| Date | DateTime? | null |
| InitialDate | DateTime | 2000-01-01 |
| MinimumDate | DateTime | 1900-01-01 |
| MaximumDate | DateTime | 2100-12-31 |
| Format | string | "d" |
| ValueTextColor | Color? | null |
Opens native time picker dialog on tap.
<tv:TimePickerCell Title="Alarm" Time="{Binding AlarmTime, Mode=TwoWay}" Format="T" />
| Property | Type | Default |
|---|---|---|
| Time | TimeSpan | 00:00:00 |
| Format | string | "t" |
| ValueTextColor | Color? | null |
Opens native dropdown/spinner picker on tap.
<tv:TextPickerCell Title="Color" ItemsSource="{Binding Colors}"
SelectedIndex="{Binding SelectedColorIndex, Mode=TwoWay}" />
| Property | Type | Default |
|---|---|---|
| ItemsSource | IList? | null |
| SelectedIndex | int | -1 |
| SelectedItem | object? | null |
| DisplayMember | string? | null |
| PickerTitle | string? | null |
| SelectedCommand | ICommand? | null |
| ValueTextColor | Color? | null |
Opens a prompt dialog for numeric input.
<tv:NumberPickerCell Title="Font Size" Number="{Binding FontSize, Mode=TwoWay}"
Min="8" Max="72" Unit="pt" />
| Property | Type | Default |
|---|---|---|
| Number | int? | null |
| Min | int | 0 |
| Max | int | 9999 |
| Unit | string | "" |
| PickerTitle | string | "Enter a number" |
| SelectedCommand | ICommand? | null |
| ValueTextColor | Color? | null |
Full-page picker for single or multi-select. Navigates to a selection page.
<!-- Single select -->
<tv:PickerCell Title="Country" ItemsSource="{Binding Countries}"
SelectionMode="Single" SelectedItem="{Binding SelectedCountry, Mode=TwoWay}"
PageTitle="Select Country" />
<!-- Multi select -->
<tv:PickerCell Title="Hobbies" ItemsSource="{Binding Hobbies}"
SelectionMode="Multiple" MaxSelectedNumber="3"
SelectedItems="{Binding SelectedHobbies, Mode=TwoWay}" />
| Property | Type | Default |
|---|---|---|
| ItemsSource | IEnumerable? | null |
| SelectedItem | object? | null |
| SelectedItems | IList? | null |
| SelectionMode | SelectionMode | Single |
| MaxSelectedNumber | int | 0 (unlimited) |
| UsePickToClose | bool | false |
| UseAutoValueText | bool | true |
| DisplayMember | string? | null |
| SubDisplayMember | string? | null |
| PageTitle | string | "Select" |
| ShowArrow | bool | true |
| KeepSelectedUntilBack | bool | false |
| SelectedCommand | ICommand? | null |
| AccentColor | Color? | null |
Hosts any custom MAUI view.
<tv:CustomCell Title="Progress">
<tv:CustomCell.CustomContent>
<ProgressBar Progress="0.75" />
</tv:CustomCell.CustomContent>
</tv:CustomCell>
| Property | Type | Default |
|---|---|---|
| CustomContent | View? | null |
| UseFullSize | bool | false |
| Command | ICommand? | null |
| LongCommand | ICommand? | null |
| ShowArrow | bool | false |
| KeepSelectedUntilBack | bool | false |
All cells inherit these properties:
| Property | Type | Default | Description |
|---|---|---|---|
| Title | string | "" | Primary text |
| TitleColor | Color? | null | Title color |
| TitleFontSize | double | -1 | Title font size |
| TitleFontFamily | string? | null | Title font family |
| TitleFontAttributes | FontAttributes? | null | Bold, Italic, None |
| Description | string | "" | Subtitle below title |
| DescriptionColor | Color? | null | Description color |
| DescriptionFontSize | double | -1 | Description font size |
| HintText | string | "" | Right of title hint |
| HintTextColor | Color? | null | Hint color |
| IconSource | ImageSource? | null | Left icon |
| IconSize | double | -1 | Icon dimensions |
| IconRadius | double | -1 | Icon corner radius |
| CellBackgroundColor | Color? | null | Background color |
| SelectedColor | Color? | null | Tap highlight color |
| IsSelectable | bool | true | Responds to taps |
| CellHeight | double | -1 | Fixed height |
| BorderColor | Color? | null | Border color |
| BorderWidth | double | -1 | Border width |
| BorderRadius | double | -1 | Border corner radius |
<tv:TableSection Title="GENERAL" FooterText="These settings apply globally"
HeaderBackgroundColor="#F2F2F7" HeaderTextColor="#666666"
UseDragSort="False">
<!-- cells -->
</tv:TableSection>
| Property | Type | Default |
|---|---|---|
| Title | string | "" |
| FooterText | string | "" |
| HeaderView | View? | null |
| FooterView | View? | null |
| IsVisible | bool | true |
| FooterVisible | bool | true |
| HeaderBackgroundColor | Color? | null |
| HeaderTextColor | Color? | null |
| HeaderFontSize | double | -1 |
| HeaderFontFamily | string? | null |
| HeaderFontAttributes | FontAttributes? | null |
| HeaderHeight | double | -1 |
| FooterTextColor | Color? | null |
| FooterFontSize | double | -1 |
| FooterBackgroundColor | Color? | null |
| UseDragSort | bool | false |
| ItemsSource | IEnumerable? | null |
| ItemTemplate | DataTemplate? | null |
| TemplateStartIndex | int | 0 |
Generate cells from a data source:
<tv:TableSection Title="Items" ItemsSource="{Binding Items}">
<tv:TableSection.ItemTemplate>
<DataTemplate>
<tv:LabelCell Title="{Binding Name}" ValueText="{Binding Value}" />
</DataTemplate>
</tv:TableSection.ItemTemplate>
</tv:TableSection>
The ItemsSource supports INotifyCollectionChanged for live updates.
Apply styles at the TableView level. Individual cell/section properties override globals.
<tv:TableView CellTitleColor="#333333"
CellTitleFontSize="17"
CellDescriptionColor="#888888"
CellValueTextColor="#007AFF"
CellBackgroundColor="White"
CellSelectedColor="#EFEFEF"
CellAccentColor="#007AFF"
CellIconSize="28"
HeaderTextColor="#666666"
HeaderFontSize="13"
HeaderBackgroundColor="#F2F2F7"
FooterTextColor="#8E8E93"
SeparatorColor="#C6C6C8"
SeparatorPadding="16"
SectionSeparatorHeight="12">
| Property | Type | Description |
|---|---|---|
| CellTitleColor | Color? | Title color for all cells |
| CellTitleFontSize | double | Title font size |
| CellTitleFontFamily | string? | Title font family |
| CellTitleFontAttributes | FontAttributes? | Title styling |
| CellDescriptionColor | Color? | Description color |
| CellDescriptionFontSize | double | Description font size |
| CellHintTextColor | Color? | Hint text color |
| CellHintTextFontSize | double | Hint font size |
| CellValueTextColor | Color? | Value text color |
| CellValueTextFontSize | double | Value font size |
| CellBackgroundColor | Color? | Cell background |
| CellSelectedColor | Color? | Tap highlight color |
| CellAccentColor | Color? | Switches, checkboxes, radios |
| CellIconSize | double | Icon dimensions |
| CellIconRadius | double | Icon corner radius |
| CellPadding | Thickness? | Cell content padding |
| CellBorderColor | Color? | Cell border color |
| CellBorderWidth | double | Cell border width |
| CellBorderRadius | double | Cell border corner radius |
| Property | Type | Default |
|---|---|---|
| HeaderBackgroundColor | Color? | null |
| HeaderTextColor | Color? | null |
| HeaderFontSize | double | -1 |
| HeaderFontFamily | string? | null |
| HeaderFontAttributes | FontAttributes | Bold |
| HeaderPadding | Thickness | 14,8,8,8 |
| HeaderHeight | double | -1 |
| HeaderTextVerticalAlign | LayoutAlignment | End |
| FooterTextColor | Color? | null |
| FooterFontSize | double | -1 |
| FooterFontAttributes | FontAttributes | None |
| FooterPadding | Thickness | 14,8,8,8 |
| FooterBackgroundColor | Color? | null |
| Property | Type | Default |
|---|---|---|
| SeparatorColor | Color? | null |
| SeparatorHeight | double | 0.5 |
| SeparatorPadding | double | 16 |
| ShowSectionSeparator | bool | true |
| SectionSeparatorHeight | double | 8 |
| SectionSeparatorColor | Color? | null |
Enable reorder controls (up/down arrows) on a section:
<tv:TableView ItemDroppedCommand="{Binding ItemDroppedCommand}">
<tv:TableRoot>
<tv:TableSection Title="Reorder" UseDragSort="True">
<tv:LabelCell Title="First" ValueText="1" />
<tv:LabelCell Title="Second" ValueText="2" />
<tv:LabelCell Title="Third" ValueText="3" />
</tv:TableSection>
</tv:TableRoot>
</tv:TableView>
The ItemDroppedCommand receives ItemDroppedEventArgs with Section, Cell, FromIndex, ToIndex.
<tv:TableView ScrollToTop="{Binding ShouldScrollTop}" ScrollToBottom="{Binding ShouldScrollBottom}" />
await tableView.ScrollToTopAsync();
await tableView.ScrollToBottomAsync();
| Event | Args | Description |
|---|---|---|
| ItemDropped | ItemDroppedEventArgs | Cell reordered via drag sort |
| ModelChanged | EventArgs | Root/sections/cells changed |
| CellPropertyChanged | CellPropertyChangedEventArgs | Cell property changed |
When generating code with Shiny.Maui.TableView:
xmlns:tv="http://shiny.net/maui/tableview" to the pagetv:TableView > tv:TableRoot > tv:TableSectionTitle and FooterTextSwitchCell for on/off togglesCheckboxCell for accept/agree checkboxesSimpleCheckCell for selection lists (shows/hides checkmark)RadioCell for mutually exclusive choices within a sectionEntryCell for text inputCommandCell for navigation/action items with disclosure arrowButtonCell for destructive or primary actionsLabelCell for read-only displayDatePickerCell / TimePickerCell for date/time selectionTextPickerCell for dropdown selection from a listNumberPickerCell for numeric input with min/maxPickerCell for full-page single or multi-selectCustomCell for any custom MAUI viewMode=TwoWay for editable properties (On, Checked, ValueText, Date, Time, Number, SelectedIndex, SelectedItem, SelectedItems)Mode=OneWay (default) for display-only properties (Title, Description, ValueText on LabelCell)Mode=OneWaytv:RadioCell.SelectedValue="{Binding Prop, Mode=TwoWay}"public class SettingsViewModel : INotifyPropertyChanged
{
private bool _wifiEnabled = true;
public bool WifiEnabled
{
get => _wifiEnabled;
set => SetProperty(ref _wifiEnabled, value);
}
public ICommand SaveCommand { get; }
public SettingsViewModel()
{
SaveCommand = new Command(async () =>
await Application.Current!.Windows[0].Page!.DisplayAlertAsync("Saved", "Settings saved.", "OK"));
}
public event PropertyChangedEventHandler? PropertyChanged;
private bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? name = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
return true;
}
}
null to inherit system defaults.Application.Current.UserAppTheme automatically.tv:TableView for consistent appearanceCellAccentColor for switches, checkboxes, and radio buttons globally<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:tv="http://shiny.net/maui/tableview"
x:Class="MyApp.SettingsPage"
Title="Settings">
<tv:TableView CellSelectedColor="#E0E0E0" CellAccentColor="#007AFF">
<tv:TableRoot>
<tv:TableSection Title="General">
<tv:SwitchCell Title="Notifications" On="{Binding NotificationsOn, Mode=TwoWay}" />
<tv:SwitchCell Title="Sound" On="{Binding SoundOn, Mode=TwoWay}" />
<tv:CheckboxCell Title="Accept Analytics" Checked="{Binding AnalyticsAccepted, Mode=TwoWay}" />
</tv:TableSection>
<tv:TableSection Title="Account">
<tv:EntryCell Title="Name" ValueText="{Binding Name, Mode=TwoWay}" Placeholder="Your name" />
<tv:EntryCell Title="Email" ValueText="{Binding Email, Mode=TwoWay}" Keyboard="Email" />
<tv:CommandCell Title="Change Password" Command="{Binding ChangePasswordCommand}" />
</tv:TableSection>
<tv:TableSection Title="Theme" tv:RadioCell.SelectedValue="{Binding Theme, Mode=TwoWay}">
<tv:RadioCell Title="Light" Value="Light" />
<tv:RadioCell Title="Dark" Value="Dark" />
<tv:RadioCell Title="System" Value="System" />
</tv:TableSection>
<tv:TableSection Title="Preferences">
<tv:DatePickerCell Title="Birthday" Date="{Binding Birthday, Mode=TwoWay}" Format="D" />
<tv:TimePickerCell Title="Daily Reminder" Time="{Binding ReminderTime, Mode=TwoWay}" />
<tv:NumberPickerCell Title="Font Size" Number="{Binding FontSize, Mode=TwoWay}"
Min="10" Max="36" Unit="pt" />
</tv:TableSection>
<tv:TableSection Title="About">
<tv:LabelCell Title="Version" ValueText="1.0.0" />
<tv:CommandCell Title="Privacy Policy" Command="{Binding PrivacyCommand}" />
<tv:CommandCell Title="Terms of Service" Command="{Binding TermsCommand}" />
</tv:TableSection>
<tv:TableSection Title="Actions">
<tv:ButtonCell Title="Sign Out" Command="{Binding SignOutCommand}" ButtonTextColor="Red" />
</tv:TableSection>
</tv:TableRoot>
</tv:TableView>
</ContentPage>
Mode=TwoWay for user-editable propertiesShowArrow="True" and KeepSelectedUntilBack="True"SelectedValue at the section levelItemsSource on sections for data-driven cellsFor detailed templates and examples, see:
reference/api-reference.md - Full API surface and property tablesreference/templates.md - Page and cell code generation templatesdata-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
OpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.
data-ai
OpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.