C#.NET自定义控件怎么动态加载普通控件?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#.NET自定义控件怎么动态加载普通控件?相关的知识,希望对你有一定的参考价值。

我想做一个自定义控件来显示一组DropDownList,而且DropDownList的数量是动态的(可以设置个属性来决定需要创建几个DropDownList),如果直接用htmlTextWriter来写下拉框的HTML,好象容易获取下拉框组的选择值,用DropDownList可是不知道这么动态加载,谁可以提供一些解决方案? 万分感谢!

参考技术A 将DropdownList作为控件添加到Controls集合
关于添加控件的方法
lizhangyong420已经说了
我就不再赘述
在Render方法中将控件中的DropdownList取出来
在需要的时候调用RenderControl方法,举个简单的例子:
public
class
CustomizeControl:WebControl

protected
override
Render(HtmlTextWriter
writer)

writer.WriteLine("<div>");
foreach(WebControl
control
in
this.Controls)

if(control
is
DropDownList)

control.RenderControl(writer);


writer.WriteLine("</div>");

ASP.net 自定义 GridView 控件

【中文标题】ASP.net 自定义 GridView 控件【英文标题】:ASP.net Custom GridView Control 【发布时间】:2012-06-07 02:11:02 【问题描述】:

我正在开发自定义 GridView 控件,需要一些帮助。如果我手动输入列名,我可以让它正确地吐出我需要的东西。现在我有2个问题。第一个是让列标题动态显示。第二个是动态填充行项目。

默认.aspx

<asp:View id="vCreateNew" runat="server">
            Content Here (View 2)...
            <trac:DataGridView id="gvMain" runat="server"  GridLines="Horizontal"  AutoGenerateColumns="False" > </trac:DataGridView>
        </asp:View>

默认.aspx.vb

Partial Class processes_ProgramTrack_Default
    Inherits Citi.CSPaper.Controls.BasePage
    Protected Sub ProgramTrackNav_MenuItemClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MenuEventArgs) Handles ProgramTrackNav.MenuItemClick
        Dim strSelection As String = ProgramTrackNav.SelectedValue
        Dim sqlDataSource As New SqlDataSource()
        sqlDataSource.ConnectionString = ConfigurationManager.ConnectionStrings("CSPaperWEBConnectionString").ConnectionString
        Select Case strSelection
            ......                
            Case "CreateNew"
                mlvNav.SetActiveView(vCreateNew)
                sqlDataSource.SelectCommand = "SELECT [ProgramNumber], [ProgramName], [ProgramStatus] FROM tblPrgTrackPrograms"
                Dim args As New DataSourceSelectArguments
                gvMain.DataSource = sqlDataSource.Select(args)
                gvMain.DataBind()
            ........
            End Select
    End Sub
End Class

GridViewControl.ascx

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="GridViewControl.ascx.vb"  Inherits="GridViewControl" %>
<asp:GridView ID="GridViewControl" runat="server" >
</asp:GridView>

GridViewControl.ascx.vb

Public Class GridViewControl
    Inherits System.Web.UI.UserControl
    Private _html As New StringBuilder()
    Private _dataSource As IEnumerable
    Private _CssClass As String
    Private _CellSpacing As String
    Public Property DataSource() As IEnumerable
        Get
            Return _dataSource
        End Get
        Set(ByVal value As IEnumerable)
            _dataSource = value
        End Set
    End Property
    Public Overridable Property CssClass() As String
        Get
            Return _CssClass
        End Get
        Set(ByVal value As String)
            _CssClass = value
        End Set
    End Property
    Public Overridable Property CellSpacing() As String
        Get
            Return _CellSpacing
        End Get
        Set(ByVal value As String)
            _CellSpacing = value
        End Set
    End Property
    Private Sub CreateBulletedList()
        Dim dataSource As IEnumerable = Nothing
        Dim i As Integer = 0
        Dim strArr() As String = "ID", "Name", "Fee"
        Try
            dataSource = Me._dataSource
        Catch
        End Try

        If Not (dataSource Is Nothing) Then
            _html.Append("<table id=""" & ClientID & """ class=""" & _CssClass & """ CellSpacing=""" & _CellSpacing & """>")
            _html.Append("<thead>" & vbCrLf & "<tr>" & vbCrLf)
            For Each Item As String In strArr
                _html.Append("<th>" & Item & "</th>" & vbCrLf)
            Next
            _html.Append("</tr>" & vbCrLf & "</thead><tbody>" & vbCrLf)
            For Each dataObject As Object In dataSource
                _html.Append("<tr>" & vbCrLf)
                For i = 0 To 2
                    _html.Append("<td>" & vbCrLf)
                    _html.Append(dataObject.Row(i))
                    _html.Append("</td>" & vbCrLf)
                Next
                _html.Append("</tr>" & vbCrLf)
            Next dataObject
            _html.Append("</tbody></table>" & vbCrLf)
        End If
    End Sub
    Public Overrides Sub DataBind()
        MyBase.OnDataBinding(EventArgs.Empty)

        CreateBulletedList()
    End Sub
    Protected Overrides Sub Render(ByVal output As HtmlTextWriter)
        output.Write(_html)
    End Sub
End Class

------------------------------------
| Table Data                       |
------------------------------------
ID  AppName            Environment
2   TestApp            UAT
3   ServerFileMaint    UAT
4   ProgramTrack       Development
5   RegZ_Stmnt_Adj     Active
6   SecInv             Decommission

我不想手动编码for i = 0 to ...,上限,但想动态地执行此操作。标题的方式相同。我遇到的问题是,如果我不对上限进行硬编码,我会收到一条错误消息,指出 Cannot find column 3.。我在编写第二个For Each 块以循环遍历包含数据的行时得到了这个。

【问题讨论】:

您有机会试用我的代码吗?还是您采取了替代路线? 【参考方案1】:

我想我明白这里发生了什么,以及如何解决它。

对我来说最大的困惑是这个块:

            For Each dataObject As Object In dataSource
                _html.Append("<tr>" & vbCrLf)
                For i = 0 To 2
                    _html.Append("<td>" & vbCrLf)
                    _html.Append(dataObject.Row(i))
                    _html.Append("</td>" & vbCrLf)
                Next
                _html.Append("</tr>" & vbCrLf)
            Next dataObject

如果 dataSource 是一个 DataSet,那么这种方法是有意义的……但不是真的,因为您想要引用 Table(0)。如果 dataSource 是一个 DataTable,那么这种方法是有意义的,除非不是真的,因为你会想要循环遍历 For Each dataObject as DataRow in dataSource.Rows。但情况似乎并非如此,因为您引用了 dataObject.Row(i)。

您可能想要做的是(在粗略/未经测试的代码中)更像这样:

            For Each dataObject As DataRow In dataSource.Rows
                _html.Append("<tr>" & vbCrLf)
                For Each col as DataColumn In dataSource.Columns
                    _html.Append("<td>" & vbCrLf)
                    _html.Append(dataObject(col).ToString())
                    _html.Append("</td>" & vbCrLf)
                Next
                _html.Append("</tr>" & vbCrLf)
            Next

这假设 dataSource 是一个 DataTable,您将遍历所有该表的行,然后对于每一行,您将遍历数据表中的所有列,并为每一列获取该行中的数据,然后显示它。

【讨论】:

以上是关于C#.NET自定义控件怎么动态加载普通控件?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET用户自定义控件

wpf中动态添加的自定义控件过宽,不能完全显示,怎么办

winform DataGridView 动态添加一列控件(自定义控件)

wpf 重新加载自定义控件出现异常

C# Winform自定义控件加载到主窗体中之后,自定控件上面的空间 怎么和主窗体上其他控件交互?

创建自定义控件并将其加载到 FormView