Skip to content
Draft
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 @@ -72,6 +72,12 @@ protected override void PreFilterProperties(IDictionary properties)
properties[nameof(Dock)] = TypeDescriptor.CreateProperty(typeof(ListBoxDesigner), dockProp, []);
}

// Wrap Items property to control editor availability based on DataSource
if (properties["Items"] is PropertyDescriptor itemsProp && Component is ListBox listBox)
{
properties["Items"] = new ItemsPropertyDescriptor(itemsProp, listBox);
}

base.PreFilterProperties(properties);
}

Expand Down Expand Up @@ -218,4 +224,47 @@ public override DesignerActionListCollection ActionLists
return _actionLists;
}
}

/// <summary>
/// Custom property descriptor that removes the editor when DataSource is set.
/// </summary>
private sealed class ItemsPropertyDescriptor : PropertyDescriptor
{
private readonly PropertyDescriptor _baseDescriptor;
private readonly ListBox _listBox;

public ItemsPropertyDescriptor(PropertyDescriptor baseDescriptor, ListBox listBox)
: base(baseDescriptor)
{
_baseDescriptor = baseDescriptor;
_listBox = listBox;
}

public override Type ComponentType => _baseDescriptor.ComponentType;

public override bool IsReadOnly => _baseDescriptor.IsReadOnly;

public override Type PropertyType => _baseDescriptor.PropertyType;

public override bool CanResetValue(object component) => _baseDescriptor.CanResetValue(component);

public override object? GetValue(object? component) => _baseDescriptor.GetValue(component);

public override void ResetValue(object component) => _baseDescriptor.ResetValue(component);

public override void SetValue(object? component, object? value) => _baseDescriptor.SetValue(component, value);

public override bool ShouldSerializeValue(object component) => _baseDescriptor.ShouldSerializeValue(component);

public override object? GetEditor(Type editorBaseType)
{
// Don't provide an editor if DataSource is set
if (_listBox.DataSource is not null)
{
return null;
}

return _baseDescriptor.GetEditor(editorBaseType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ public void InvokeItemsDialog()

public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection returnItems =
[
new DesignerActionMethodItem(this, "InvokeItemsDialog",
DesignerActionItemCollection returnItems = [];

// Only show "Edit Items..." if DataSource is not set
if (Component is ListControl control && control.DataSource is null)
{
returnItems.Add(new DesignerActionMethodItem(this, "InvokeItemsDialog",
SR.ListControlUnboundActionListEditItemsDisplayName,
SR.ItemsCategoryName,
SR.ListControlUnboundActionListEditItemsDescription, true),
];
SR.ListControlUnboundActionListEditItemsDescription, true));
}

return returnItems;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@ namespace System.Windows.Forms.Design.Tests;
public sealed class ListControlUnboundActionListTests : IDisposable
{
private readonly ComponentDesigner _designer;
private readonly Mock<IComponent> _componentMock;
private readonly ListBox _listBox;
private readonly ListControlUnboundActionList _actionList;

public ListControlUnboundActionListTests()
{
_designer = new();
_componentMock = new();
_designer.Initialize(_componentMock.Object);
_listBox = new();
_designer.Initialize(_listBox);
_actionList = new(_designer);
}

public void Dispose() => _designer.Dispose();
public void Dispose()
{
_designer.Dispose();
_listBox.Dispose();
}

[Fact]
public void Constructor_ShouldInitializeDesigner() => _actionList.Should().NotBeNull();

[Fact]
public void GetSortedActionItems_ShouldReturnCorrectItems()
public void GetSortedActionItems_ShouldReturnCorrectItems_WhenDataSourceIsNull()
{
DesignerActionItemCollection items = _actionList.GetSortedActionItems();

Expand All @@ -39,4 +43,15 @@ public void GetSortedActionItems_ShouldReturnCorrectItems()
methodItem.Category.Should().Be(SR.ItemsCategoryName);
methodItem.Description.Should().Be(SR.ListControlUnboundActionListEditItemsDescription);
}

[Fact]
public void GetSortedActionItems_ShouldReturnEmpty_WhenDataSourceIsSet()
{
_listBox.DataSource = new List<string> { "Item1", "Item2" };

DesignerActionItemCollection items = _actionList.GetSortedActionItems();

items.Should().NotBeNull();
items.Count.Should().Be(0);
}
}
Loading