2

我正在尝试开发一个控件,该控件允许开发人员通过标记填充集合(例如,用属性 PersistenceMode(PersistenceMode.InnerProperty) 装饰的属性。我有一个来自Brian 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>

就像现在一样,当我尝试编译时,我得到一个编译器错误,它只是说对象实例未设置为上面一行中的对象实例。如果我把它拿出来,页面加载得很好,设置对象反映了标记中的值。为什么我无法正确填充集合?

4

2 回答 2

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在子控件中使用,这样它就不会尝试匹配实际的类。

于 2010-07-30T21:07:47.660 回答
0

如果要解析多个子条目,则必须实现自己的 Parser。您需要使您的子类成为用户控件并覆盖“AddParsedSubObject”。这是您的 RssFeedCollection 的新版本,它将接受由回车而不是 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
于 2010-07-30T18:49:29.570 回答