在 ASP.NET Webform 中扩展 DropDownList

Posted

技术标签:

【中文标题】在 ASP.NET Webform 中扩展 DropDownList【英文标题】:Extending DropDownList in ASP.NET Webform 【发布时间】:2021-01-31 12:32:09 【问题描述】:

我正在尝试创建自己的下拉列表以在网页上使用,但我无法让它按照我想要的方式工作。

在最基本的形式中,我可以创建一个类,从 System.Web.UI.WebControls.DropDownList 继承,在页面上注册它,添加标记,它至少会在页面上显示一个控件:

我的班级:

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace CustomDropdown
    <DefaultProperty("Text"), ToolboxData("<0:DropDownListWithAttributes runat=server></0:DropDownListWithAttributes>")>
    Public Class DropDownListWithAttributes
        Inherits System.Web.UI.WebControls.DropDownList

    End Class
End Namespace

页面注册:

<%@ Register TagPrefix="myControls" Namespace="CustomDropdown" %>

标记:

<myControls:DropDownListWithAttributes ID="ddlMyTestCustomDDL" runat="server"></myControls:DropDownListWithAttributes>

但就是这样。这是我所能得到的。我根本无法从后面的代码访问它。就好像它不存在一样。我需要能够用项目、触发事件等填充它...普通下拉列表可以做的所有事情。

标记似乎认为它可以有事件:

但是当我添加一个时,设计师会中断:

所以我没有获得正常的 ddl 功能,我无法从后面的代码访问控件,添加任何类型的事件都会破坏东西......我不知道如何使这项工作发挥作用:(

【问题讨论】:

您是否在创建此自定义控件后尝试清理并重新编译您的项目? 是的。我建造/重建/清理和重建。我想我只是不明白创建这些类型的服务器控件的整个过程以及它们有什么能力和没有能力......叹息 自定义控件是否在单独的项目中?如果是这样,它可能需要在Namespace CustomDropdown 声明之前使用&lt;Assembly: TagPrefix("CustomDropdown", "myControls")&gt;。除了ToolboxData 属性之外,它还需要Imports System.Security.PermissionsAspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level:=AspNetHostingPermissionLevel.Minimal) 属性。 我把它和我的网页放在同一个项目中。但我想我会试一试并将它移到它自己的项目中。我像 Andrew 建议的那样添加了程序集和安全性,并修复了它,但它仍然无法在后面的代码中访问。我清理,重建了十几次,但没有运气。所以我开始从安德鲁的建议中删除一些东西并将其添加回来......一直在清理和重建。突然间,我在设计器文件中找到了一个很好的参考,并且在后面的代码中无法访问它。 您说它在您的代码隐藏中无法访问,但您能否在标记中添加“OnSelectedIndexChanged”偶数处理程序,并为您生成代码隐藏代码? 【参考方案1】:

嗯,根据 Andrew 的建议并将其转移到自己的项目中,它现在似乎正在运行。这是它的样子:

C# 类库:带有单个 .cs 文件的 DropDownWithAttributes:DropDownListWithAttributes.cs

using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: TagPrefix("DropDownWithAttributes", "myControl")]
namespace DropDownWithAttributes

    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [DefaultProperty("Text")]
    [ToolboxData("<0:ServerControl1 runat=server></0:ServerControl1>")]
    public class DropDownListWithAttributes : DropDownList
    
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        protected override object SaveViewState()
        
            // create object array for Item count + 1
            object[] allStates = new object[this.Items.Count + 1];

            // the +1 is to hold the base info
            object baseState = base.SaveViewState();
            allStates[0] = baseState;

            Int32 i = 1;
            // now loop through and save each Style attribute for the List
            foreach (ListItem li in this.Items)
            
                Int32 j = 0;
                string[][] attributes = new string[li.Attributes.Count][];
                foreach (string attribute in li.Attributes.Keys)
                
                    attributes[j++] = new string[]  attribute, li.Attributes[attribute] ;
                
                allStates[i++] = attributes;
            
            return allStates;
        

        protected override void LoadViewState(object savedState)
        
            if (savedState != null)
            
                object[] myState = (object[])savedState;

                // restore base first
                if (myState[0] != null)
                    base.LoadViewState(myState[0]);

                Int32 i = 1;
                foreach (ListItem li in this.Items)
                
                    // loop through and restore each style attribute
                    foreach (string[] attribute in (string[][])myState[i++])
                    
                        li.Attributes[attribute[0]] = attribute[1];
                    
                
            
        
    

我将项目添加到我的解决方案中,并从我的 Web 项目中添加了对 DropDownWithAttributes 的引用:

在我的页面上注册:

<%@ Register TagPrefix="myControl" Namespace="DropDownWithAttributes" Assembly="DropDownWithAttributes" %>

在页面上添加控件:

<myControl:DropDownListWithAttributes ID="ddlWithAttribute" runat="server" OnSelectedIndexChanged="ddlWithAttribute_SelectedIndexChanged"></myControl:DropDownListWithAttributes>

这就是之前发生故障的地方......现在看起来好多了:

 '''<summary>
    '''ddlWithAttribute control.
    '''</summary>
    '''<remarks>
    '''Auto-generated field.
    '''To modify move field declaration from designer file to code-behind file.
    '''</remarks>
    Protected WithEvents ddlWithAttribute As Global.DropDownWithAttributes.DropDownListWithAttributes

【讨论】:

以上是关于在 ASP.NET Webform 中扩展 DropDownList的主要内容,如果未能解决你的问题,请参考以下文章

如何在同一个 Visual Studio 解决方案中设置 ASP Classic 和 ASP.NET WebForm - 用于在 ASP.NET WebForm 中重写 ASP Classic 页面

沐雪微信|asp.net 微信源码 多用户平台 c# webform 源码

如何在asp.net C# Webform中制作像网格一样的Excel

求asp.net webform 工作的流程

浅析ASP.NET Webform和ASP.NET MVC

如何在 asp.net webform 中获取 js POST?