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,47 @@ 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();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I’ve added an explicit assertion for the initial state after AddItems so the behavior is clearly verified. Updated in the latest commit.


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

listBox.SelectedIndex = 2;
a.UpdateEnabled();
up.Enabled.Should().BeTrue();
down.Enabled.Should().BeFalse();

listBox.ClearSelected();
listBox.SelectedIndex = 0;
a.UpdateEnabled();
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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. I’ve updated the test to call UpdateEnabled() explicitly after selection changes to avoid relying on event wiring. Included in the latest commit.

listBox.ClearSelected();
listBox.SelectedIndex = 1;
a.UpdateEnabled();
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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agree with this. I’ve added an explicit UpdateEnabled() call after the state changes to ensure we’re validating the correct state. Fixed in the latest commit.

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

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