Skip to content

Commit 247cb05

Browse files
Copilotcsharpfritz
andauthored
Implement DropDownList component with shared ListItem infrastructure (#282)
Co-authored-by: csharpfritz <78577+csharpfritz@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Jeffrey T. Fritz <csharpfritz@users.noreply.github.com>
1 parent a268094 commit 247cb05

16 files changed

Lines changed: 917 additions & 1 deletion

File tree

.nuget/nuget.exe

7.88 MB
Binary file not shown.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ There are a significant number of controls in ASP.NET Web Forms, and we will foc
2929
- Calendar
3030
- [CheckBox](docs/EditorControls/CheckBox.md)
3131
- CheckBoxList
32-
- DropDownList
32+
- [DropDownList](docs/EditorControls/DropDownList.md)
3333
- FileUpload
3434
- [HiddenField](docs/EditorControls/HiddenField.md)
3535
- [HyperLink](docs/EditorControls/HyperLink.md)
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# DropDownList
2+
3+
The DropDownList component renders an HTML `<select>` element that allows users to select a single item from a drop-down list. This component supports both static items and data-bound scenarios.
4+
5+
Original Web Forms documentation: https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.dropdownlist?view=netframework-4.8
6+
7+
## Blazor Features Supported
8+
9+
- Static items via `StaticItems` parameter with `ListItem` collection
10+
- Data binding via `Items` parameter with `DataTextField` and `DataValueField`
11+
- Two-way binding with `@bind-SelectedValue`
12+
- Selected item tracking via `SelectedValue` and `SelectedIndex`
13+
- OnSelectedIndexChanged event handler
14+
- Disabled state via `Enabled` parameter
15+
- Style attributes (BackColor, ForeColor, Font, etc.) and CssClass formatting
16+
- Access to `SelectedItem` property
17+
18+
## WebForms Features Not Supported
19+
20+
- AutoPostBack is not supported in Blazor - use `OnSelectedIndexChanged` event instead
21+
- AppendDataBoundItems is not implemented
22+
- DataSourceID is not supported - bind directly to collections via `Items` parameter
23+
24+
## WebForms Syntax
25+
26+
```html
27+
<asp:DropDownList
28+
AccessKey="string"
29+
AutoPostBack="True|False"
30+
BackColor="color name|#dddddd"
31+
BorderColor="color name|#dddddd"
32+
BorderStyle="NotSet|None|Dotted|Dashed|Solid|Double|Groove|Ridge|Inset|Outset"
33+
BorderWidth="size"
34+
CssClass="string"
35+
DataSourceID="string"
36+
DataTextField="string"
37+
DataValueField="string"
38+
Enabled="True|False"
39+
EnableTheming="True|False"
40+
EnableViewState="True|False"
41+
Font-Bold="True|False"
42+
Font-Italic="True|False"
43+
Font-Names="string"
44+
Font-Overline="True|False"
45+
Font-Size="string|Smaller|Larger|XX-Small|X-Small|Small|Medium|Large|X-Large|XX-Large"
46+
Font-Strikeout="True|False"
47+
Font-Underline="True|False"
48+
ForeColor="color name|#dddddd"
49+
Height="size"
50+
ID="string"
51+
OnDataBinding="DataBinding event handler"
52+
OnDisposed="Disposed event handler"
53+
OnInit="Init event handler"
54+
OnLoad="Load event handler"
55+
OnPreRender="PreRender event handler"
56+
OnSelectedIndexChanged="SelectedIndexChanged event handler"
57+
OnUnload="Unload event handler"
58+
runat="server"
59+
SelectedIndex="number"
60+
SelectedValue="string"
61+
TabIndex="integer"
62+
ToolTip="string"
63+
Visible="True|False"
64+
Width="size">
65+
66+
<asp:ListItem Value="value1" Text="Display Text 1" Selected="True|False" />
67+
<asp:ListItem Value="value2" Text="Display Text 2" />
68+
69+
</asp:DropDownList>
70+
```
71+
72+
## Blazor Syntax
73+
74+
### Static Items
75+
76+
```razor
77+
<DropDownList TItem="object" StaticItems="items" @bind-SelectedValue="selectedValue" />
78+
79+
@code {
80+
private string selectedValue = "";
81+
82+
private ListItemCollection items = new()
83+
{
84+
new ListItem("Select...", ""),
85+
new ListItem("Option One", "1"),
86+
new ListItem("Option Two", "2"),
87+
new ListItem("Option Three", "3")
88+
};
89+
}
90+
```
91+
92+
### Data Binding
93+
94+
```razor
95+
<DropDownList TItem="Product"
96+
Items="products"
97+
DataTextField="Name"
98+
DataValueField="Id"
99+
@bind-SelectedValue="selectedProductId" />
100+
101+
@code {
102+
private string selectedProductId = "";
103+
104+
private List<Product> products = new()
105+
{
106+
new Product { Id = "1", Name = "Widget" },
107+
new Product { Id = "2", Name = "Gadget" },
108+
new Product { Id = "3", Name = "Gizmo" }
109+
};
110+
111+
public class Product
112+
{
113+
public string Id { get; set; }
114+
public string Name { get; set; }
115+
}
116+
}
117+
```
118+
119+
### With Event Handler
120+
121+
```razor
122+
<DropDownList TItem="object"
123+
StaticItems="items"
124+
@bind-SelectedValue="selectedValue"
125+
OnSelectedIndexChanged="HandleSelectionChanged" />
126+
127+
@code {
128+
private string selectedValue = "";
129+
130+
private void HandleSelectionChanged(ChangeEventArgs e)
131+
{
132+
var newValue = e.Value?.ToString();
133+
Console.WriteLine($"Selection changed to: {newValue}");
134+
}
135+
}
136+
```
137+
138+
### With Styling
139+
140+
```razor
141+
<DropDownList TItem="object"
142+
StaticItems="items"
143+
CssClass="form-select"
144+
BackColor="new WebColor(System.Drawing.Color.LightYellow)"
145+
Font="new FontInfo { Bold = true }" />
146+
```
147+
148+
## Key Differences from Web Forms
149+
150+
1. **Type Parameter**: Blazor DropDownList requires a `TItem` type parameter for data binding
151+
2. **Property Names**: Use `StaticItems` for the item collection (not `Items`), as `Items` is reserved for data-bound scenarios
152+
3. **Two-way Binding**: Use `@bind-SelectedValue` for automatic two-way binding
153+
4. **Events**: Use `OnSelectedIndexChanged` with `ChangeEventArgs` instead of specialized event args
154+
5. **No AutoPostBack**: Blazor's event model doesn't require postback; events fire immediately
155+
156+
## ListItem and ListItemCollection
157+
158+
The `ListItem` class represents individual items in the dropdown:
159+
160+
```csharp
161+
public class ListItem
162+
{
163+
public string Text { get; set; }
164+
public string Value { get; set; }
165+
public bool Selected { get; set; }
166+
public bool Enabled { get; set; } = true;
167+
168+
public ListItem(string text)
169+
public ListItem(string text, string value)
170+
public ListItem(string text, string value, bool selected)
171+
}
172+
```
173+
174+
The `ListItemCollection` class provides helper methods:
175+
176+
```csharp
177+
public class ListItemCollection : List<ListItem>
178+
{
179+
public ListItem FindByValue(string value)
180+
public ListItem FindByText(string text)
181+
}
182+
```
183+
184+
## Common Patterns
185+
186+
### Pre-select an Item
187+
188+
```razor
189+
<DropDownList TItem="object" StaticItems="items" SelectedValue="2" />
190+
```
191+
192+
### Disabled DropDownList
193+
194+
```razor
195+
<DropDownList TItem="object" StaticItems="items" Enabled="false" />
196+
```
197+
198+
### Get Selected Item Details
199+
200+
```csharp
201+
var dropdown = // reference to DropDownList component
202+
var selectedItem = dropdown.SelectedItem;
203+
var text = selectedItem?.Text;
204+
var value = selectedItem?.Value;
205+
```
206+
207+
## Migration Tips
208+
209+
When migrating from Web Forms:
210+
211+
1. Replace `<asp:DropDownList>` with `<DropDownList TItem="object">`
212+
2. Rename any `Items` parameter to `StaticItems`
213+
3. Replace `AutoPostBack="true"` with `OnSelectedIndexChanged` event handler
214+
4. Use `@bind-SelectedValue` instead of manually managing `SelectedValue`
215+
5. Remove `runat="server"` attribute
216+
6. Remove `<asp:ListItem>` tags and define items in code-behind as `ListItemCollection`
217+
218+
## See Also
219+
220+
- [ListBox](ListBox.md) - Multiple selection list control
221+
- [CheckBoxList](CheckBoxList.md) - Multiple checkboxes in a list
222+
- [RadioButtonList](RadioButtonList.md) - Radio button selection list

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ nav:
6565
- Editor Controls:
6666
- AdRotator: EditorControls/AdRotator.md
6767
- Button: EditorControls/Button.md
68+
- DropDownList: EditorControls/DropDownList.md
6869
- CheckBox: EditorControls/CheckBox.md
6970
- HiddenField: EditorControls/HiddenField.md
7071
- HyperLink: EditorControls/HyperLink.md
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
@page "/ControlSamples/DropDownList"
2+
3+
<h1>DropDownList Component Samples</h1>
4+
5+
<h2>Basic DropDownList with Static Items</h2>
6+
<DropDownList TItem="object" StaticItems="staticItems" @bind-SelectedValue="selectedStatic" />
7+
<p>Selected Value: <strong>@selectedStatic</strong></p>
8+
9+
<h2>With Pre-selected Value</h2>
10+
<DropDownList TItem="object" StaticItems="preselectedItems" SelectedValue="banana" />
11+
12+
<h2>Data-bound DropDownList</h2>
13+
<DropDownList TItem="Product"
14+
Items="products"
15+
DataTextField="Name"
16+
DataValueField="Id"
17+
@bind-SelectedValue="selectedProduct" />
18+
<p>Selected Product ID: <strong>@selectedProduct</strong></p>
19+
<p>Selected Product: <strong>@(products.FirstOrDefault(p => p.Id == selectedProduct)?.Name ?? "None")</strong></p>
20+
21+
<h2>Disabled DropDownList</h2>
22+
<DropDownList TItem="object" StaticItems="staticItems" Enabled="false" SelectedValue="2" />
23+
24+
<h2>With CSS Class</h2>
25+
<DropDownList TItem="object" StaticItems="styledItems" CssClass="form-select" />
26+
<br />
27+
<small>Note: The form-select class is from Bootstrap and provides styling.</small>
28+
29+
<h2>With Inline Styles</h2>
30+
<DropDownList TItem="object"
31+
StaticItems="colorItems"
32+
BackColor="new WebColor(System.Drawing.Color.LightYellow)"
33+
ForeColor="new WebColor(System.Drawing.Color.Navy)"
34+
Font="new FontInfo { Bold = true }" />
35+
36+
<h2>With Change Event</h2>
37+
<DropDownList TItem="object"
38+
StaticItems="eventItems"
39+
@bind-SelectedValue="eventSelection"
40+
OnSelectedIndexChanged="HandleSelectionChanged" />
41+
<p>Last selection: <strong>@lastSelection</strong> at @lastChangeTime.ToString("HH:mm:ss")</p>
42+
43+
@code {
44+
private string selectedStatic = "";
45+
private string selectedProduct = "";
46+
private string eventSelection = "";
47+
private string lastSelection = "None";
48+
private DateTime lastChangeTime = DateTime.Now;
49+
50+
private ListItemCollection staticItems = new()
51+
{
52+
new ListItem("Select...", ""),
53+
new ListItem("Option One", "1"),
54+
new ListItem("Option Two", "2"),
55+
new ListItem("Option Three", "3")
56+
};
57+
58+
private ListItemCollection preselectedItems = new()
59+
{
60+
new ListItem("Apple", "apple"),
61+
new ListItem("Banana", "banana"),
62+
new ListItem("Cherry", "cherry")
63+
};
64+
65+
private ListItemCollection styledItems = new()
66+
{
67+
new ListItem("Styled Option", "1"),
68+
new ListItem("Another Option", "2")
69+
};
70+
71+
private ListItemCollection colorItems = new()
72+
{
73+
new ListItem("Colored dropdown item", "1"),
74+
new ListItem("Another colored item", "2")
75+
};
76+
77+
private ListItemCollection eventItems = new()
78+
{
79+
new ListItem("Select one...", ""),
80+
new ListItem("First", "1"),
81+
new ListItem("Second", "2"),
82+
new ListItem("Third", "3")
83+
};
84+
85+
private List<Product> products = new()
86+
{
87+
new Product { Id = "1", Name = "Widget" },
88+
new Product { Id = "2", Name = "Gadget" },
89+
new Product { Id = "3", Name = "Gizmo" },
90+
new Product { Id = "4", Name = "Doohickey" }
91+
};
92+
93+
private void HandleSelectionChanged(ChangeEventArgs e)
94+
{
95+
lastSelection = e.Value?.ToString() ?? "None";
96+
lastChangeTime = DateTime.Now;
97+
StateHasChanged();
98+
}
99+
100+
public class Product
101+
{
102+
public string Id { get; set; }
103+
public string Name { get; set; }
104+
}
105+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BeforeWebForms.ControlSamples.DropDownList.Default" %>
2+
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
3+
<h2>DropDownList Control Samples</h2>
4+
5+
<h3>Basic DropDownList with Static Items</h3>
6+
<asp:DropDownList ID="ddlStatic" runat="server">
7+
<asp:ListItem Text="Select..." Value="" />
8+
<asp:ListItem Text="Option One" Value="1" />
9+
<asp:ListItem Text="Option Two" Value="2" />
10+
<asp:ListItem Text="Option Three" Value="3" />
11+
</asp:DropDownList>
12+
13+
<h3>With Pre-selected Value</h3>
14+
<asp:DropDownList ID="ddlSelected" runat="server">
15+
<asp:ListItem Text="Apple" Value="apple" />
16+
<asp:ListItem Text="Banana" Value="banana" Selected="True" />
17+
<asp:ListItem Text="Cherry" Value="cherry" />
18+
</asp:DropDownList>
19+
20+
<h3>Data-bound DropDownList</h3>
21+
<asp:DropDownList ID="ddlDataBound" DataTextField="Name" DataValueField="Id" runat="server" />
22+
23+
<h3>Disabled DropDownList</h3>
24+
<asp:DropDownList ID="ddlDisabled" Enabled="false" runat="server">
25+
<asp:ListItem Text="Cannot change" Value="1" />
26+
</asp:DropDownList>
27+
28+
<h3>With CSS Class</h3>
29+
<asp:DropDownList ID="ddlStyled" CssClass="form-select" runat="server">
30+
<asp:ListItem Text="Styled" Value="1" />
31+
</asp:DropDownList>
32+
33+
<h3>With Inline Styles</h3>
34+
<asp:DropDownList ID="ddlColors" BackColor="LightYellow" ForeColor="Navy"
35+
Width="200px" runat="server">
36+
<asp:ListItem Text="Colored dropdown" Value="1" />
37+
</asp:DropDownList>
38+
</asp:Content>

0 commit comments

Comments
 (0)