2010-07-30 57 views
2

我想开发一个控件,允许开发人员通过标记来填充集合(例如,用属性PersistenceMode(PersistenceMode.InnerProperty)装饰的属性,我有一个exampleBrian Chavez,更多以下我想要做什么,但我想有从用户控件控制继承,而不是控制用户控件和内部属性的问题

这里是我在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

如果你想解析多个子条目,你必须实现你自己的解析器。您需要让您的子类成为用户控件并覆盖“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 
+0

感谢您的回复。这可能工作,但我知道布赖恩查韦斯的网站上的例子按预期工作,并没有涉及到这一点,我想避免使RssFeedCollection成为用户控件,当它真的更适合作为简单对象的简单集合时 – 2010-07-30 18:56:38

+0

@EDIT:它只需要从Control继承,我的错误。 – 2010-07-30 19:03:25

+0

我添加了一个新的解决方案。旧的仍然有助于强调使用“AddParsedSubObject”方法,但是新的方法允许您正确使用属性。 – 2010-07-30 21:15:02

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,因此它不会尝试匹配实际的类。