2010-07-30 4 views
2

개발자가 태그 (예 : PersistenceMode (PersistenceMode.InnerProperty) 특성으로 장식 된 속성)를 사용하여 컬렉션을 채울 수있는 컨트롤을 개발하려고합니다. example에서 Brian Chavez 이하는 내가 원하는 것을하지만 난 UserControl에서 제어 상속을 가지고 제어하지하려면 여기 UserControl 및 내부 속성 문제

제가 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 
<%@ 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> 

처럼ASCX 파일은 보인다 인스턴스가 위의 행에있는 객체의 인스턴스로 설정되지 않았습니다. 태그를 꺼내면 페이지가 잘로드되고 설정 객체는 태그의 값을 반영합니다. 왜 컬렉션이 올바르게 채워지는 데 문제가 있습니까?

답변

0

여러 하위 항목을 구문 분석하려면 고유 한 파서를 구현해야합니다. 자녀 클래스를 사용자 정의 컨트롤로 만들고 "AddParsedSubObject"를 재정의해야합니다. 다음은 RssResource 객체 대신 Carriage Returns로 구분 된 여러 문자열을 허용하는 RssFeedCollection의 새 버전입니다. 구문 분석기를 고급 수준으로 만들고 문자열 대신 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

답변 해 주셔서 감사합니다. 이것은 작동하지만 Brian Chavez의 사이트가 예상대로 작동한다는 것을 알고 있으며이 작업을 포함하지 않으며 RssFeedCollection을 단순한 객체의 간단한 컬렉션으로 더 잘 어울리는 UserControl으로 만드는 것을 피하고 싶습니다. –

+0

@EDIT : Control 만 상속 받아야합니다. 저의 실수입니다. –

+0

새로운 솔루션을 추가했습니다. 이전 버전은 여전히 ​​"AddParsedSubObject"메소드의 사용을 강조하는 데 유용하지만 새로 추가 된 속성을 사용하면 해당 속성을 올바르게 사용할 수 있습니다. –

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을 사용하지 마십시오. 따라서 실제 클래스와 일치하지 않습니다.