Mr.Tの場所

特攻野郎Aチームじゃないよー

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  253  : 記事  0  : コメント  3733  : トラックバック  52

ニュース

  • 性別:男
  • 猫1:まる
  • 猫2:もろ
  • 猫3:にゃん左部郎
  • タバコ:男は黙ってJPS
[わんくま同盟] C#, VB.NET 掲示板

書庫

日記カテゴリ

Mr.Tです、こんにちは。

http://blogs.wankuma.com/mrt/archive/2007/09/13/96121.aspx#FeedBackの続きになりますかね。

そもそも、Evalを使わないとなると明示的にCastすることになります。Castはいいんですが、

<ItemTemplate>
  <tr>
    <td><%# ((DbDataRecord)Container.DataItem).GetString(0) %></td>
    <td><%# ((DbDataRecord)Container.DataItem).GetInt(1) %></td>
  </tr>
</ItemTemplate>

こんな使い方になりますね。(C#ですけど)えらく面倒というか、やはりもっと明示的に、直感的に指定したいです。

たとえば、表示したいViewは、こんなのとします。

工場コード 工場名
10 工場A
20 工場B
30 工場C

 単なるマスタですが、そもそもこんな感じで表示するケースが基本じゃないかと思います。

で、これを表示するためのソースです。

(データソースコントロール)

Namespace MRT.OriginalControls

    '製造原価関連データベースへのアクセス用 データソース基底クラス
    '    データソースクラス
    <AspNetHostingPermission(SecurityAction.LinkDemand, _
    level:=AspNetHostingPermissionLevel.Minimal), _
    AspNetHostingPermission(SecurityAction.InheritanceDemand, _
    level:=AspNetHostingPermissionLevel.Minimal), _
    ToolboxData("<{0}:OriginalDataSource runat=""Server""/>"), _
    Description("カスタムデータソース")> _
    Public Class OriginalSource
        Inherits DataSourceControl

        '        Implements IDataSourceOtherControlParameter

        Private Const DefaultViewName As String = "defaultview"

        '唯一のView名を返す
        Protected Overrides Function GetViewNames() As System.Collections.ICollection
            Dim viewNames() As String = New String() {DefaultViewName}
            Return CType(viewNames, ICollection)
        End Function

        '既定のViewを返す
        Private _defaultView As OriginalDataSorceView
        Private ReadOnly Property DefaultView() As OriginalDataSorceView
            Get
                If (_defaultView Is Nothing) Then
                    _defaultView = New OriginalDataSorceView(Me, DefaultViewName)
                End If
                Return _defaultView
            End Get
        End Property

        Protected Overrides Function GetView(ByVal viewName As String) As System.Web.UI.DataSourceView
            If (viewName = String.Empty) Or _
                (viewName.ToLower = DefaultViewName.ToLower) Then

                Return DefaultView
            End If
            Throw New ArgumentOutOfRangeException(viewName)
        End Function
    End Class

    '規定のDataSourceView
    Public Class OriginalDataSorceView
        Inherits DataSourceView
        '       Implements IDataSourceOtherControlParameter

        Private _owner As OriginalSource
        Public Sub New(ByVal owner As OriginalSource, ByVal name As String)
            MyBase.New(owner, name)
            _owner = owner
        End Sub 'New

        'ここでSelectしまっせ。
        Protected Overrides Function ExecuteSelect(ByVal arguments As System.Web.UI.DataSourceSelectArguments) As System.Collections.IEnumerable

            Dim connectionString As String = "Data Source=****"
            Dim targetStoredProcedure As String = "dbo.GetFactoryTable"
            Dim targetDataReader As SqlDataReader
            Dim targetView As Queue(Of FactoryView) = New Queue(Of FactoryView)

            Using targetSQLConnection As SqlConnection = New SqlConnection(connectionString)
                Using targetSQLCommand As SqlCommand = New SqlCommand(targetStoredProcedure, targetSQLConnection)

                    '処理はパラメータ追加してのち、ストアドで実行
                    targetSQLCommand.Connection.Open()

                    targetSQLCommand.CommandType = CommandType.StoredProcedure
                    targetDataReader = targetSQLCommand.ExecuteReader(CommandBehavior.CloseConnection)

                    Dim fieldsCount As Integer = targetDataReader.FieldCount
                    While targetDataReader.Read()
                        Dim newView As FactoryView = New FactoryView
                        newView.FactoryCD = targetDataReader.GetValue(0).ToString
                        newView.FactoryName = targetDataReader.GetValue(1).ToString
                        targetView.Enqueue(newView)
                    End While

                    Return targetView
                End Using
            End Using

        End Function
    End Class

    'アクセスされるView
    Public Class FactoryView

        Private _factoryCD As String
        Public Property FactoryCD() As String
            Get
                Return _factoryCD
            End Get
            Set(ByVal value As String)
                _factoryCD = value
            End Set
        End Property

        Private _factoryName As String
        Public Property FactoryName() As String
            Get
                Return _factoryName
            End Get
            Set(ByVal value As String)
                _factoryName = value
            End Set
        End Property
    End Class

End Namespace

(表示コントロール)

Namespace MRT.OriginalControls

    'リスト表示するためのカスタムコントロール
    <AspNetHostingPermission(System.Security.Permissions.SecurityAction.Demand, _
    level:=AspNetHostingPermissionLevel.Minimal), _
    AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, _
    level:=AspNetHostingPermissionLevel.Minimal), _
    ToolboxData("<{0}:OriginalList runat=""Server""></{0}:OriginalList>"), _
    Description("リスト表示用カスタム"), _
    ParseChildren(True)> _
    Public Class OriginalList
        Inherits CompositeDataBoundControl

        Private targetItemTemplate As ITemplate

        'コンテナ設定箇所
        <PersistenceMode(PersistenceMode.InnerProperty), _
        TemplateContainer(GetType(MasterContainer))> _
        Public Overridable Property ItemTemplate() As ITemplate
            Get
                Return targetItemTemplate
            End Get
            Set(ByVal value As ITemplate)
                targetItemTemplate = value
            End Set
        End Property

        'コントロール作成部分
        Protected Overrides Function CreateChildControls(ByVal dataSource As IEnumerable, _
                 ByVal dataBinding As Boolean) As Integer
            Dim loopCount As Integer = 0
            Dim targetEnumerator As IEnumerator = dataSource.GetEnumerator
            Dim listItemView As MasterContainer

            Controls.Clear()
            While targetEnumerator.MoveNext()

                listItemView = New MasterContainer(CType(targetEnumerator.Current, FactoryView))
                'テンプレートへの格納
                '上記のITemplateは、テンプレート適用のためのプロパティ
                targetItemTemplate.InstantiateIn(listItemView)
                If (dataBinding = True) Then
                    'バインドしないものはデータバインド処理にならない
                    listItemView.DataBind()
                End If

                Controls.Add(listItemView)
                loopCount += 1
            End While

            Return loopCount
        End Function
    End Class

    'コンテナ
    Public Class MasterContainer
        Inherits Control
        Implements INamingContainer '一意の名前をつけるために必要

        Public Sub New(ByVal targetView As FactoryView)
            FactoryItem = targetView
        End Sub

        Private _factoryItem As FactoryView
        Public Property FactoryItem() As FactoryView
            Get
                Return _factoryItem
            End Get
            Set(ByVal value As FactoryView)
                _factoryItem = value
            End Set
        End Property
    End Class
End Namespace

(ASPXファイル)

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register TagPrefix="MyControl" Namespace="MRT.OriginalControls"%>

<!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">   
    <MyControl:OriginalSource runat="server" ID="OriginalDataSource1" />
    <table border ="1">
    <MyControl:OriginalList runat="server" ID="list1" DataSourceID="OriginalDataSource1">
    <ItemTemplate>
        <tr><td><%# container.FactoryItem.FactoryCD%></td><td><%# container.FactoryItem.FactoryName%></td></tr>
    </ItemTemplate>
    </MyControl:OriginalList>
    </table>
    </form>
</body>
</html>

 

とりあえず、ひとつのViewだけが対象になってるので、ソレ(ここではFactoryView)しか出てきません。
それに、取得条件も変更できるようにはなっていませんが...

container.FactoryItem.FactoryCD

こうやって、かけるようになりました。ありがとう>菊池さん

さて、菊池さんのBlogではExecuteSelectの部分がのってません。当たり前ですが、ここは何を扱うかで中身が
違うからなんですね。

キモは、IEnumerable で返さないといけないってことです。
今回はQueueを使いましたが、順序とか特にきにしないなら、Listでも返せます。

投稿日時 : 2007年9月16日 16:43

コメント

No comments posted yet.

Post Feedback

タイトル
名前
Url:
コメント