Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1037,9 +1037,11 @@ private void UpdateEnabled()
}

bool editEnabled = (_listBox.SelectedItem is not null) && CollectionEditable;
int count = _listBox.Items.Count;
int selectedIndex = _listBox.SelectedIndex;
_removeButton.Enabled = editEnabled && AllowRemoveInstance(((ListItem)_listBox.SelectedItem!).Value);
_upButton.Enabled = editEnabled && _listBox.Items.Count > 1;
_downButton.Enabled = editEnabled && _listBox.Items.Count > 1;
_upButton.Enabled = editEnabled && count > 1 && selectedIndex > 0;
_downButton.Enabled = editEnabled && count > 1 && selectedIndex < count - 1;
_propertyGrid.Enabled = editEnabled;
_addButton.Enabled = CollectionEditable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,41 @@ namespace System.ComponentModel.Design.Tests;

public class CollectionEditorTests
{
[Fact]
public void CollectionEditor_CollectionForm_UpdateEnabled_FirstMiddleLastNone_SetsUpDownExpected()
{
SubCollectionEditor editor = new(typeof(List<int>));
using Form form = editor.CreateCollectionForm();

dynamic a = form.TestAccessor.Dynamic;
a.AddItems(new object[] { 1, 2, 3 });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The test implicitly assumes AddItems selects the last added item (index 2). If AddItems behavior changes in the future, this test will fail without a clear reason.

Consider adding an explicit assertion on the initial state:

a.AddItems(new object[] { 1, 2, 3 });

// AddItems selects the last added item by default
listBox.SelectedIndex.Should().Be(2);
up.Enabled.Should().BeTrue();
down.Enabled.Should().BeFalse();


ListBox listBox = (ListBox)a._listBox;
Button up = (Button)a._upButton;
Button down = (Button)a._downButton;

up.Enabled.Should().BeTrue();
down.Enabled.Should().BeFalse();

listBox.SelectedIndex = 0;
up.Enabled.Should().BeFalse();
down.Enabled.Should().BeTrue();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This test relies on the SelectedIndexChanged event being wired up to call UpdateEnabled() automatically. In a test environment (where the form is never shown), the event wiring may not be fully initialized, making this test fragile.

Consider calling UpdateEnabled() explicitly after each selection change to make the test deterministic:

listBox.SelectedIndex = 0;
a.UpdateEnabled();  // Don't rely on event — call explicitly
up.Enabled.Should().BeFalse();

This also makes the test more readable — it's clear we're testing the logic of UpdateEnabled(), not the event wiring.

listBox.ClearSelected();
listBox.SelectedIndex = 1;
up.Enabled.Should().BeTrue();
down.Enabled.Should().BeTrue();

listBox.ClearSelected();
up.Enabled.Should().BeFalse();
down.Enabled.Should().BeFalse();

listBox.Items.Clear();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: After listBox.Items.Clear(), SelectedIndex becomes -1. If UpdateEnabled() is not triggered by the clear operation, the button states here could be stale values from the previous assertions rather than reflecting the current state.

Same recommendation: call a.UpdateEnabled() explicitly after AddItems to ensure we're verifying the actual logic, not leftover state.

a.AddItems(new object[] { 42 });
up.Enabled.Should().BeFalse();
down.Enabled.Should().BeFalse();
}

[Theory]
[InlineData(typeof(object), typeof(object))]
[InlineData(typeof(string), typeof(object))]
Expand Down
Loading