我正在尝试开发一个控件,允许开发人员通过标记填充集合(例如,使用属性PersistenceMode(PersistenceMode.InnerProperty)修饰的属性。我有来自example的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>
现在当我尝试编译时,我得到一个编译器错误,简单地说对象实例没有设置为上面一行上的对象实例。如果我把它取出,页面加载就好了,Settings对象反映了标记中的值。为什么我无法正确填充集合?
答案 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
,因此它不会尝试匹配实际的类。