有人能推荐一个asp的dropdownlist控件吗.net(3.5),可以呈现选项组?谢谢

推荐答案

I've used the standard control in the past, and just added a simple ControlAdapter for it that would override the default behavior so it could render <optgroup>s in certain places. This works great even if you have controls that don't need the special behavior, because the additional feature doesn't get in the way.

请注意,这是为特定目的编写的,并且是用.NET2.0编写的,因此它可能不太适合您,但至少应该给您一个起点.此外,您还必须在项目中使用.browserfile将其挂钩(有关示例,请参阅本文末尾的示例).

'This codes makes the dropdownlist control recognize items with "--"
'for the label or items with an OptionGroup attribute and render them
'as <optgroup> instead of <option>.
Public Class DropDownListAdapter
    Inherits System.Web.UI.WebControls.Adapters.WebControlAdapter

    Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
        Dim list As DropDownList = Me.Control
        Dim currentOptionGroup As String
        Dim renderedOptionGroups As New Generic.List(Of String)

        For Each item As ListItem In list.Items
            Page.ClientScript.RegisterForEventValidation(list.UniqueID, item.Value)
            If item.Attributes("OptionGroup") IsNot Nothing Then
                'The item is part of an option group
                currentOptionGroup = item.Attributes("OptionGroup")
                If Not renderedOptionGroups.Contains(currentOptionGroup) Then
                    'the header was not written- do that first
                    'TODO: make this stack-based, so the same option group can be used more than once in longer select element (check the most-recent stack item instead of anything in the list)
                    If (renderedOptionGroups.Count > 0) Then
                        RenderOptionGroupEndTag(writer) 'need to close previous group
                    End If
                    RenderOptionGroupBeginTag(currentOptionGroup, writer)
                    renderedOptionGroups.Add(currentOptionGroup)
                End If
                RenderListItem(item, writer)
            ElseIf item.Text = "--" Then 'simple separator
                RenderOptionGroupBeginTag("--", writer)
                RenderOptionGroupEndTag(writer)
            Else
                'default behavior: render the list item as normal
                RenderListItem(item, writer)
            End If
        Next item

        If renderedOptionGroups.Count > 0 Then
            RenderOptionGroupEndTag(writer)
        End If
    End Sub

    Private Sub RenderOptionGroupBeginTag(ByVal name As String, ByVal writer As HtmlTextWriter)
        writer.WriteBeginTag("optgroup")
        writer.WriteAttribute("label", name)
        writer.Write(HtmlTextWriter.TagRightChar)
        writer.WriteLine()
    End Sub

    Private Sub RenderOptionGroupEndTag(ByVal writer As HtmlTextWriter)
        writer.WriteEndTag("optgroup")
        writer.WriteLine()
    End Sub

    Private Sub RenderListItem(ByVal item As ListItem, ByVal writer As HtmlTextWriter)
        writer.WriteBeginTag("option")
        writer.WriteAttribute("value", item.Value, True)
        If item.Selected Then
            writer.WriteAttribute("selected", "selected", False)
        End If

        For Each key As String In item.Attributes.Keys
            writer.WriteAttribute(key, item.Attributes(key))
        Next key

        writer.Write(HtmlTextWriter.TagRightChar)
        HttpUtility.HtmlEncode(item.Text, writer)
        writer.WriteEndTag("option")
        writer.WriteLine()
    End Sub
End Class

下面是同一类的C#实现:

/* This codes makes the dropdownlist control recognize items with "--"
 * for the label or items with an OptionGroup attribute and render them
 * as <optgroup> instead of <option>.
 */
public class DropDownListAdapter : WebControlAdapter
{
    protected override void RenderContents(HtmlTextWriter writer)
    {
        //System.Web.HttpContext.Current.Response.Write("here");
        var list = (DropDownList)this.Control;
        string currentOptionGroup;
        var renderedOptionGroups = new List<string>();

        foreach (ListItem item in list.Items)
        {
            Page.ClientScript.RegisterForEventValidation(list.UniqueID, item.Value);
            //Is the item part of an option group?
            if (item.Attributes["OptionGroup"] != null)
            {
                currentOptionGroup = item.Attributes["OptionGroup"];
                //Was the option header already written, then just render the list item
                if (renderedOptionGroups.Contains(currentOptionGroup))
                    RenderListItem(item, writer);
                //The header was not written,do that first
                else
                {
                    //Close previous group
                    if (renderedOptionGroups.Count > 0)
                        RenderOptionGroupEndTag(writer);

                    RenderOptionGroupBeginTag(currentOptionGroup, writer);
                    renderedOptionGroups.Add(currentOptionGroup);
                    RenderListItem(item, writer);
                }
            }
            //Simple separator
            else if (item.Text == "--")
            {
                RenderOptionGroupBeginTag("--", writer);
                RenderOptionGroupEndTag(writer);
            }
            //Default behavior, render the list item as normal
            else
                RenderListItem(item, writer);
        }

        if (renderedOptionGroups.Count > 0)
            RenderOptionGroupEndTag(writer);
    }

    private void RenderOptionGroupBeginTag(string name, HtmlTextWriter writer)
    {
        writer.WriteBeginTag("optgroup");
        writer.WriteAttribute("label", name);
        writer.Write(HtmlTextWriter.TagRightChar);
        writer.WriteLine();
    }
    private void RenderOptionGroupEndTag(HtmlTextWriter writer)
    {
        writer.WriteEndTag("optgroup");
        writer.WriteLine();
    }
    private void RenderListItem(ListItem item, HtmlTextWriter writer)
    {
        writer.WriteBeginTag("option");
        writer.WriteAttribute("value", item.Value, true);
        if (item.Selected)
            writer.WriteAttribute("selected", "selected", false);

        foreach (string key in item.Attributes.Keys)
            writer.WriteAttribute(key, item.Attributes[key]);

        writer.Write(HtmlTextWriter.TagRightChar);
        HttpUtility.HtmlEncode(item.Text, writer);
        writer.WriteEndTag("option");
        writer.WriteLine();
    }
}

我的浏览器文件名为"App_Browsers\BrowserFile.Browser",如下所示:

<!--
    You can find existing browser definitions at
    <windir>\Microsoft.NET\Framework\<ver>\CONFIG\Browsers
-->
<browsers>
   <browser refID="Default">
      <controlAdapters>
        <adapter controlType="System.Web.UI.WebControls.DropDownList" 
               adapterType="DropDownListAdapter" />
      </controlAdapters>
   </browser>
</browsers>

Asp.net相关问答推荐

在Docker Windows中,ASP.NET核心容器在自定义端口8080上运行,但ASP.NET容器在固定端口80上运行

Web API 自托管 - 在所有网络接口上绑定

ReportViewer 控件 - 高度问题

Azure Service Fabric 是否与 Docker 做同样的事情?

说服遗留应用程序 VB6 开发人员切换到 C#

ASP.NET Core 1.0 ConfigurationBuilder().AddJsonFile("appsettings.json");找不到文件

如何在 IISExpress 上使用带有 localhost 的子域?

将 ListItem 的 ASP.NET 列表数据绑定到 DropDownList 问题

在 Blazor 中 Select 框绑定

如何为角色以及特定用户使用自定义授权属性?

MVC 3视图中的当前上下文中不存在名称'HTML'

如何在 ASP.NET MVC3 中配置区域

如何设置默认页面 asp.net

跟踪点有什么用途?

ASP.NET 中的全局资源与本地资源

如何获得 System.Diagnostics.Process 的输出?

解析器错误消息:无法加载类型网络营销

*.csproj 中的 usevshostingprocess 是什么?

如何获取部署在 Azure 网站上的 ASP.NET 5 应用程序的错误详细信息?

如何在 ASP.Net MVC 3 中返回 HttpNotFound() 的视图?