2010-07-30 44 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,因此它不會嘗試匹配實際的類。