Skip to content

feat: Implement 16 ListView CRUD events#9

Open
csharpfritz wants to merge 4 commits intodevfrom
squad/356-listview-crud-events
Open

feat: Implement 16 ListView CRUD events#9
csharpfritz wants to merge 4 commits intodevfrom
squad/356-listview-crud-events

Conversation

@csharpfritz
Copy link
Owner

Closes FritzAndFriends#356

Completes EventArgs property parity for ListView CRUD events to match the System.Web.UI.WebControls originals.

All 16 events already wired with [Parameter] EventCallback declarations and HandleCommand routing. This PR adds missing dictionary properties to EventArgs types.

Changes:

  • ListViewInsertEventArgs: add Values (IOrderedDictionary)
  • ListViewUpdateEventArgs: add Keys, OldValues, NewValues (IOrderedDictionary)
  • ListViewDeleteEventArgs: add Keys, Values (IOrderedDictionary)
  • ListViewPagePropertiesChangingEventArgs: add TotalRowCount

csharpfritz and others added 4 commits March 2, 2026 23:30
Add missing Web Forms-parity properties to ListView EventArgs types:

- ListViewInsertEventArgs: add Values (IOrderedDictionary)
- ListViewUpdateEventArgs: add Keys, OldValues, NewValues (IOrderedDictionary)
- ListViewDeleteEventArgs: add Keys, Values (IOrderedDictionary)
- ListViewPagePropertiesChangingEventArgs: add TotalRowCount

All 16 events were already wired with [Parameter] EventCallbacks and
HandleCommand routing. This commit completes EventArgs property parity
with System.Web.UI.WebControls originals.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document all 16 ListView lifecycle events covering insert, update, delete,
edit/cancel, sorting, paging, selection, and lifecycle categories. Each event
includes EventArgs property tables, Web Forms to Blazor syntax comparison
tabs, and practical usage examples. Updated Features section and Blazor
syntax block to reflect the complete event surface.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
43 comprehensive tests covering all ListView CRUD event pairs:
- Insert: ItemInserting/ItemInserted (firing, cancellation, order, AffectedRows)
- Update: ItemUpdating/ItemUpdated (firing, cancellation, order, KeepInEditMode)
- Delete: ItemDeleting/ItemDeleted (firing, cancellation, order, AffectedRows)
- Edit: ItemEditing (EventArgs, modified NewEditIndex, cancellation)
- Cancel: ItemCanceling (CancelMode edit vs insert, cancellation vetoes)
- Sort: Sorting/Sorted (order, cancellation, toggle direction, new expression)
- Paging: PagePropertiesChanging/PagePropertiesChanged (order, args, zero values)
- Selection: SelectedIndexChanging/SelectedIndexChanged (order, cancellation, modified index)
- LayoutCreated (items present, empty list, custom layout)
- ItemCreated (OnAfterRenderAsync first render)
- DataBound/ItemDataBound (per-item firing)
- HandleCommand routing (case-insensitive, unknown commands, null sort arg)
- Full CRUD cycles (Edit->Update, Edit->Cancel, Delete->Insert)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment on lines +658 to +725
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

_layoutCreatedFired.ShouldBeTrue();
}

[Fact]
public void LayoutCreated_DoesNotFireWhenItemsEmpty()
{
Widget[] emptyItems = Array.Empty<Widget>();
var cut = Render(@<ListView Items="emptyItems"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
<EmptyItemTemplate><div>No data</div></EmptyItemTemplate>
</ListView>);

_layoutCreatedFired.ShouldBeFalse();
}

[Fact]
public void LayoutCreated_FiresWithCustomLayoutTemplate()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
<LayoutTemplate Context="itemPlaceholder">
<div class="custom-layout">@itemPlaceholder</div>
</LayoutTemplate>
</ListView>);

_layoutCreatedFired.ShouldBeTrue();
cut.FindAll("div.custom-layout").Count.ShouldBe(1);
}

// ═════════════════════════════════════════════════════════════════
// ITEM CREATED
// ═════════════════════════════════════════════════════════════════

[Fact]
public async Task ItemCreated_FiresOnFirstRender()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
ItemCreated="OnItemCreated"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

// ItemCreated fires in OnAfterRenderAsync(firstRender: true)
// Trigger a render cycle to ensure the event fires
await cut.InvokeAsync(() => { });

_itemCreatedFired.ShouldBeTrue();
}

// ═════════════════════════════════════════════════════════════════
// DATA BOUND (override)
// ═════════════════════════════════════════════════════════════════

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
cut
is useless, since its value is never read.

Copilot Autofix

AI about 7 hours ago

In general, to fix a "useless assignment to local variable" you either remove the unused variable (if its value is not needed) or start using it meaningfully. Here, the test LayoutCreated_FiresWhenItemsExist never uses cut, and only needs the side effect of rendering the ListView to trigger OnLayoutCreated. The simplest, behavior‑preserving change is to call Render(...) without assigning its result to cut.

Concretely, in src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor, within the LayoutCreated_FiresWhenItemsExist method (around line 658), replace var cut = Render(@<ListView ... with a bare Render(@<ListView ... call. No additional methods, imports, or definitions are required.

Suggested changeset 1
src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
--- a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
+++ b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
@@ -655,7 +655,7 @@
 	[Fact]
 	public void LayoutCreated_FiresWhenItemsExist()
 	{
-		var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
+		Render(@<ListView Items="Widget.SimpleWidgetList"
 						ItemType="Widget"
 						OnLayoutCreated="OnLayoutCreated"
 						Context="Item">
EOF
@@ -655,7 +655,7 @@
[Fact]
public void LayoutCreated_FiresWhenItemsExist()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +672 to +743
var cut = Render(@<ListView Items="emptyItems"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
<EmptyItemTemplate><div>No data</div></EmptyItemTemplate>
</ListView>);

_layoutCreatedFired.ShouldBeFalse();
}

[Fact]
public void LayoutCreated_FiresWithCustomLayoutTemplate()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
<LayoutTemplate Context="itemPlaceholder">
<div class="custom-layout">@itemPlaceholder</div>
</LayoutTemplate>
</ListView>);

_layoutCreatedFired.ShouldBeTrue();
cut.FindAll("div.custom-layout").Count.ShouldBe(1);
}

// ═════════════════════════════════════════════════════════════════
// ITEM CREATED
// ═════════════════════════════════════════════════════════════════

[Fact]
public async Task ItemCreated_FiresOnFirstRender()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
ItemCreated="OnItemCreated"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

// ItemCreated fires in OnAfterRenderAsync(firstRender: true)
// Trigger a render cycle to ensure the event fires
await cut.InvokeAsync(() => { });

_itemCreatedFired.ShouldBeTrue();
}

// ═════════════════════════════════════════════════════════════════
// DATA BOUND (override)
// ═════════════════════════════════════════════════════════════════

[Fact]
public void DataBound_FiresAfterAllItemsRendered()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnDataBound="OnDataBound"
OnItemDataBound="OnItemDataBound"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

_dataBoundCount.ShouldBeGreaterThan(0);
_itemDataBoundCount.ShouldBeGreaterThanOrEqualTo(Widget.SimpleWidgetList.Length);
}

[Fact]
public void DataBound_ItemDataBound_FiresPerItem()
{

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
cut
is useless, since its value is never read.

Copilot Autofix

AI about 7 hours ago

General fix: when a local variable is assigned a value that is never read, either remove the variable (and just execute the expression for its side effects) or, if the value is actually needed, add the missing read/use. Here, the expression Render(@<ListView ...>) is required for its side effects (rendering the component and triggering events), but the returned cut is not used, so we should remove the variable and keep just the call.

Best fix in this file: in LayoutCreated_DoesNotFireWhenItemsEmpty, change the line var cut = Render(...); to just Render(...);. This keeps the render side effect, preserves test behavior, and removes the unused local variable. No additional imports, methods, or definitions are needed; it's a single-line change within src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor.

Concretely:

  • In LayoutCreated_DoesNotFireWhenItemsEmpty (around line 672), replace the declaration/assignment var cut = Render(@<ListView ... with a standalone call Render(@<ListView ....
  • The rest of the method and file remain unchanged.

Suggested changeset 1
src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
--- a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
+++ b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
@@ -669,7 +669,7 @@
 	public void LayoutCreated_DoesNotFireWhenItemsEmpty()
 	{
 		Widget[] emptyItems = Array.Empty<Widget>();
-		var cut = Render(@<ListView Items="emptyItems"
+		Render(@<ListView Items="emptyItems"
 						ItemType="Widget"
 						OnLayoutCreated="OnLayoutCreated"
 						Context="Item">
EOF
@@ -669,7 +669,7 @@
public void LayoutCreated_DoesNotFireWhenItemsEmpty()
{
Widget[] emptyItems = Array.Empty<Widget>();
var cut = Render(@<ListView Items="emptyItems"
Render(@<ListView Items="emptyItems"
ItemType="Widget"
OnLayoutCreated="OnLayoutCreated"
Context="Item">
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +729 to +813
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnDataBound="OnDataBound"
OnItemDataBound="OnItemDataBound"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

_dataBoundCount.ShouldBeGreaterThan(0);
_itemDataBoundCount.ShouldBeGreaterThanOrEqualTo(Widget.SimpleWidgetList.Length);
}

[Fact]
public void DataBound_ItemDataBound_FiresPerItem()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnItemDataBound="OnItemDataBound"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

// bUnit may trigger multiple render cycles; ensure at least one fire per item
_itemDataBoundCount.ShouldBeGreaterThanOrEqualTo(Widget.SimpleWidgetList.Length);
}

// ═════════════════════════════════════════════════════════════════
// COMMAND ROUTING: HandleCommand dispatches to correct event
// ═════════════════════════════════════════════════════════════════

[Fact]
public void HandleCommand_UnknownCommand_FiresItemCommandWithArgs()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
ItemCommand="OnCommand"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

cut.InvokeAsync(() => theListView.HandleCommand("Approve", "request-42", 0));

_commandArgs.ShouldNotBeNull();
_commandArgs.CommandName.ShouldBe("Approve");
_commandArgs.CommandArgument.ShouldBe("request-42");
}

[Fact]
public void HandleCommand_CaseInsensitive_RoutesCorrectly()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
ItemEditing="OnEditing"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

cut.InvokeAsync(() => theListView.HandleCommand("EDIT", null, 0));

_editingArgs.ShouldNotBeNull();
_editingArgs.NewEditIndex.ShouldBe(0);
}

[Fact]
public void HandleCommand_Sort_PassesCommandArgumentAsSortExpression()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
Sorting="OnSorting"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

cut.InvokeAsync(() => theListView.HandleCommand("Sort", "Price", 0));

_sortingArgs.ShouldNotBeNull();
_sortingArgs.SortExpression.ShouldBe("Price");
}

[Fact]
public void HandleCommand_Sort_NullArgument_UsesEmptyString()
{

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
cut
is useless, since its value is never read.

Copilot Autofix

AI about 7 hours ago

In general, to fix a "useless assignment to local variable" you either (1) remove the variable and just evaluate the expression for its side effects, if you don't need the result, or (2) start using the variable meaningfully if the result is actually needed. Here, the Render(...) call is required for its side effects (rendering the ListView and triggering data-bound events), but the cut variable itself is never used in DataBound_FiresAfterAllItemsRendered.

The best minimal fix without changing existing functionality is to remove the var cut = part and simply call Render(...) as a standalone statement. This preserves the render and event wiring but eliminates the unused local variable. Concretely, in src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor, in the DataBound_FiresAfterAllItemsRendered method (starting at line 727), replace the line var cut = Render(@<ListView ... with Render(@<ListView ... and keep the rest of the method unchanged. No new imports, methods, or definitions are needed.

Suggested changeset 1
src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
--- a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
+++ b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
@@ -726,7 +726,7 @@
 	[Fact]
 	public void DataBound_FiresAfterAllItemsRendered()
 	{
-		var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
+		Render(@<ListView Items="Widget.SimpleWidgetList"
 						ItemType="Widget"
 						OnDataBound="OnDataBound"
 						OnItemDataBound="OnItemDataBound"
EOF
@@ -726,7 +726,7 @@
[Fact]
public void DataBound_FiresAfterAllItemsRendered()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnDataBound="OnDataBound"
OnItemDataBound="OnItemDataBound"
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +744 to +811
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnItemDataBound="OnItemDataBound"
Context="Item">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

// bUnit may trigger multiple render cycles; ensure at least one fire per item
_itemDataBoundCount.ShouldBeGreaterThanOrEqualTo(Widget.SimpleWidgetList.Length);
}

// ═════════════════════════════════════════════════════════════════
// COMMAND ROUTING: HandleCommand dispatches to correct event
// ═════════════════════════════════════════════════════════════════

[Fact]
public void HandleCommand_UnknownCommand_FiresItemCommandWithArgs()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
ItemCommand="OnCommand"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

cut.InvokeAsync(() => theListView.HandleCommand("Approve", "request-42", 0));

_commandArgs.ShouldNotBeNull();
_commandArgs.CommandName.ShouldBe("Approve");
_commandArgs.CommandArgument.ShouldBe("request-42");
}

[Fact]
public void HandleCommand_CaseInsensitive_RoutesCorrectly()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
ItemEditing="OnEditing"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

cut.InvokeAsync(() => theListView.HandleCommand("EDIT", null, 0));

_editingArgs.ShouldNotBeNull();
_editingArgs.NewEditIndex.ShouldBe(0);
}

[Fact]
public void HandleCommand_Sort_PassesCommandArgumentAsSortExpression()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
Sorting="OnSorting"
Context="Item"
@ref="theListView">
<ItemTemplate><span>@Item.Name</span></ItemTemplate>
</ListView>);

cut.InvokeAsync(() => theListView.HandleCommand("Sort", "Price", 0));

_sortingArgs.ShouldNotBeNull();
_sortingArgs.SortExpression.ShouldBe("Price");
}

[Fact]

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
cut
is useless, since its value is never read.

Copilot Autofix

AI about 7 hours ago

To fix this type of issue, you remove the unnecessary local variable or actually use it meaningfully. Here, the Render(...) call is needed (to perform the render and trigger data bound events), but the cut variable itself is not, since it is never read. The most direct fix that preserves all behavior is to keep the Render(...) call but drop the var cut = part.

Concretely, in src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor, inside the DataBound_ItemDataBound_FiresPerItem test method, replace the line starting with var cut = Render(@<ListView ... with a call to Render(@<ListView ... without assigning to any variable. The rest of the method, including the subsequent assertion on _itemDataBoundCount, remains unchanged. No new imports, methods, or definitions are needed.

Suggested changeset 1
src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
--- a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
+++ b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
@@ -741,7 +741,7 @@
 	[Fact]
 	public void DataBound_ItemDataBound_FiresPerItem()
 	{
-		var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
+		Render(@<ListView Items="Widget.SimpleWidgetList"
 						ItemType="Widget"
 						OnItemDataBound="OnItemDataBound"
 						Context="Item">
EOF
@@ -741,7 +741,7 @@
[Fact]
public void DataBound_ItemDataBound_FiresPerItem()
{
var cut = Render(@<ListView Items="Widget.SimpleWidgetList"
Render(@<ListView Items="Widget.SimpleWidgetList"
ItemType="Widget"
OnItemDataBound="OnItemDataBound"
Context="Item">
Copilot is powered by AI and may make mistakes. Always verify output.
ListView<Widget> theListView;

// ── Event tracking ──
List<string> _eventOrder = new();

Check notice

Code scanning / CodeQL

Missed 'readonly' opportunity Note test

Field '_eventOrder' can be 'readonly'.

Copilot Autofix

AI about 7 hours ago

To fix the problem, the field _eventOrder should be declared as readonly so that its variable reference cannot be reassigned after initialization, while still allowing modifications to the list contents. This aligns with CodeQL’s recommendation and guards against accidental reassignment in future changes.

Concretely, in src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor, within the @code block, update the declaration on line 13 from List<string> _eventOrder = new(); to readonly List<string> _eventOrder = new();. No other fields are flagged, and no additional methods, imports, or definitions are required, because readonly is a standard C# modifier and collection mutation (e.g., _eventOrder.Add(...)) remains fully supported.

Suggested changeset 1
src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
--- a/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
+++ b/src/BlazorWebFormsComponents.Test/ListView/ListViewCrudEventTests.razor
@@ -10,7 +10,7 @@
 	ListView<Widget> theListView;
 
 	// ── Event tracking ──
-	List<string> _eventOrder = new();
+	readonly List<string> _eventOrder = new();
 	ListViewEditEventArgs _editingArgs;
 	ListViewCancelEventArgs _cancelingArgs;
 	ListViewDeleteEventArgs _deletingArgs;
EOF
@@ -10,7 +10,7 @@
ListView<Widget> theListView;

// ── Event tracking ──
List<string> _eventOrder = new();
readonly List<string> _eventOrder = new();
ListViewEditEventArgs _editingArgs;
ListViewCancelEventArgs _cancelingArgs;
ListViewDeleteEventArgs _deletingArgs;
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement ListView CRUD events (16 missing)

1 participant