UserControl和内部属性的问题

时间:2010-07-30 16:53:28

标签: asp.net vb.net user-controls webusercontrol

我正在尝试开发一个控件,允许开发人员通过标记填充集合(例如,使用属性PersistenceMode(PersistenceMode.InnerProperty)修饰的属性。我有来自exampleBrian Chavez或多或少做我想要的但我希望控件继承自UserControl而不是Control。

以下是我在vb.net中的代码:

AggregateFeeds.ascx.vb

Imports Microsoft.VisualBasic

<ParseChildren(True)>
<PersistChildren(False)>
Public Class AggregateFeeds
    Inherits UserControl

    Public Sub New()
        MyBase.New()
        Me.Feeds = New RssFeedCollection()
        Me.Settings = New AggregateSettings()
    End Sub

    Private _Feeds As RssFeedCollection
    Private _Settings As AggregateSettings

    <PersistenceMode(PersistenceMode.InnerProperty)>
    Public Property Feeds As RssFeedCollection
        Get
            Return _Feeds
        End Get
        Private Set(ByVal value As RssFeedCollection)
            _Feeds = value
        End Set
    End Property

    <PersistenceMode(PersistenceMode.InnerProperty)>
    Public Property Settings As AggregateSettings
        Get
            Return _Settings
        End Get
        Private Set(ByVal value As AggregateSettings)
            _Settings = value
        End Set
    End Property
End Class

Public Class AggregateSettings
    Public Property TimeOut As Integer
    Public Property CacheResults As Boolean

    Public Sub New()
        TimeOut = 100
        CacheResults = True
    End Sub

End Class

Public Class RssFeedCollection
    Inherits List(Of RssResource)
End Class

Public Class RssResource
    Public Property Url As String = String.Empty
End Class

ascx文件看起来像:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="ucAdminTabControl.ascx.vb" Inherits="AggregateFeeds" %>

我的测试页面非常简单,看起来像:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Test.aspx.vb" Inherits="Test" %>
<%@ Register Src="~/Survey/Controls/ucAdminTabControl.ascx" TagName="AggregateFeeds" TagPrefix="uc" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc:AggregateFeeds runat="server" ID="af">
            <Settings CacheResults="False" TimeOut="250" />   
            <Feeds>
                <uc:RssResource Url="http://test.com" />
            </Feeds>        
        </uc:AggregateFeeds>        
    </div>
    </form>
</body>
</html>

现在当我尝试编译时,我得到一个编译器错误,简单地说对象实例没有设置为上面一行上的对象实例。如果我把它取出,页面加载就好了,Settings对象反映了标记中的值。为什么我无法正确填充集合?

2 个答案:

答案 0 :(得分:0)

如果要解析多个子条目,则必须实现自己的Parser。您需要使您的子类成为用户控件并覆盖“AddParsedSubObject”。这是一个新版本的RssFeedCollection,它将接受由Carriage Returns而不是RssResource对象分隔的多个字符串。如果你仍然需要它,你可以使解析器更高级并解析XML而不是字符串。

<ParseChildren(False)>
<PersistChildren(False)>
Public Class RssFeedCollection
    Inherits Web.UI.Control

    Private _URLs As String()
    Public ReadOnly Property URLs As String()
        Get
            Return _URLs
        End Get
    End Property

    Protected Overrides Sub AddParsedSubObject(ByVal obj As Object)
        Dim s = DirectCast(obj, LiteralControl).Text.Trim.Replace(" ", "") 'remove spaces
        Dim separator = New Char() {Microsoft.VisualBasic.vbCr(0)}

        _URLs = s.Split(separator, System.StringSplitOptions.RemoveEmptyEntries)

        MyBase.AddParsedSubObject(obj)
    End Sub
End Class

答案 1 :(得分:0)

这是一个更简单的解决方案。我为此示例删除了AggregateSettings;该代码应该像以前一样工作。

这是我正在使用的ASPX。

    <uc:AggregateFeeds runat="server" ID="af">
        <Feeds>
            <RssResource Url="Test1" />
            <RssResource Url="Test2" />
            <RssResource Url="Test3" />
        </Feeds>
    </uc:AggregateFeeds>

这是用户控制代码。

Partial Class AggregateFeeds
    Inherits System.Web.UI.UserControl

    Private _Feeds As New MyFeedsClass(Me)

    <PersistenceMode(PersistenceMode.InnerProperty)>
    Public ReadOnly Property Feeds As MyFeedsClass
        Get
            Return _Feeds
        End Get
    End Property
End Class

Public Class MyFeedsClass
    Inherits ControlCollection

    Sub New(ByVal owner As Control)
        MyBase.New(owner)
    End Sub

    Public Overrides Sub Add(ByVal child As System.Web.UI.Control)
        MyBase.Add(New Feed(child))
    End Sub
End Class


Public Class Feed
    Inherits HtmlGenericControl

    Sub New(ByVal GenericControl As HtmlGenericControl)
        MyBase.New()
        Me.Url = GenericControl.Attributes("Url")
    End Sub

    Public Property Url As String = String.Empty

    Public Overrides Function ToString() As String
        Return Me.Url
    End Function
End Class

它假设每个子控件都是一个html泛型控件。不要在子控件中使用<uc,因此它不会尝试匹配实际的类。