2009-05-07 7 views
4

申し訳ありませんが、それは私が思いつくことができる最高のテーマです。私は偉大なグリッドコントロールを使用していますイベントを処理するために代理人を使用

、スーパーリスト、lはここにある:あなたが問題を読む前に

http://www.codeproject.com/KB/list/outlooklistcontrol.aspx?fid=449232&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=276

は、あなたは非常に小さなVB.NET 2005のサンプルアプリをダウンロードすることができますので、ご注意くださいいますデモ問題:

http://dokmanovich.com/Documents/SuperListEvents.zip

私の質問への答えは、私は願って、私が達成しようとしているものの文脈で私はより良いダイナミックな事象を理解するのに役立ちます取得。

グリッドは次のように機能します。グリッドに列を追加するときは、実行時に値を返すイベントハンドラのアドレスを指定します。この場合、CC_ItemValueAccessor関数。後者の関数は、この場合は「ToDo」オブジェクトである入力パラメータで呼び出されます。各ToDoオブジェクトは、グリッド内で1つの行としてレンダリングされます。 CC_ItemValueAccessor関数の仕事は、渡されたToDoオブジェクトに対応する行のグリッドによって表示される列値を返すことです。

私は次のステップにそれを取るまで、これが正常に動作します:

私は動的にしたい実行時に列を作成します。たとえば、ユーザー指定のSQLを実行した結果として返されるデータテーブルの出力を表示したいとします。

前述の静的アプローチを使用して、渡された行オブジェクトのグリッド内の各列の値を返す1つのcolumnItemValueAccessor関数があります。さて、SQLの返された結果に基づいて実行時に列が決定されるので、すべての列を処理し、このイベントをトリガした列の名前を決定し、その列の値を返します単一のパラメータとして渡される行オブジェクト。

問題は、ItemValueAccessor関数は行オブジェクトのみを含むシグネチャを持ち、すべての列が同じItemValueAccessor関数にフックされているため、どの列名が必要かを判断する方法がわかりません。イベントハンドラ。

これはコントロールの単なる制限であり、この問題を克服するためには基本的なカスタムコントロールを強化する必要があると思われますが、これはC#で書かれた高度なコントロールであるためVBの男です。

ここでは、コードです:

Private Sub AddCcColumn() 
    Dim NewColumn As New BinaryComponents.SuperList.Column("CC", "CC", 110, AddressOf Cc_ItemValueAccessor) 
    _SuperList.Columns.Add(NewColumn) 
End Sub 

Private Function Cc_ItemValueAccessor(ByVal rowItem As Object) As Object 
    Dim ToDo As ToDo = CType(rowItem, SrToDoAndException).ToDo 
    Return ToDo.CCs.ToString 
End Function 

「---------------------------

そして、ここにあるが、列のインスタンス化メソッドのシグニチャーと、処理するプロシージャーを指定する最後のパラメーターの定義は、列の値を戻す原因となるイベント・ハンドラーを識別します。 BinaryComponents.SuperListの メンバー

ます。Public Sub新(文字列、文字列、整数としてByVal幅、BinaryComponents.SuperList.ColumnItemValueAccessorとしてByVal columnItemValueAccessorとしてByValキャプションとしてByVal名)。(System.IntPtrとしてオブジェクトとしてByValオブジェクト、ByValの方法)カラム

ます。Public Sub新BinaryComponents.SuperList.ColumnItemValueAccessor

の メンバー

は、誰もが何か提案を持っていますか、私は立ち往生していますか?私は本当にこのコントロールの幻想的なグループ化機能を利用したいと思っています。そのため、ユーザは、自分が望む任意の列でSQLの動的出力をグループ化できる動的出力を表示できます。

私は上記のサイトで著者に質問しましたが、回答はありませんでした。これはこれを行う方法を見つける絶好の試みです。

私と一緒にお越しいただきありがとうございます。私は、この質問が、第三者のコントロールを参照しているという事実に基づいて拒否されないことを願っています。私の希望は、その答えは、より普遍的な話題である代議員のより良い理解にあるということです。

+0

Lambaのコメントは興味深いですが、私はもっと助けが必要です。 問題を本質的なものに取り除き、何が必要であるかを示すコメントを追加して、実際の例を作成しました。あなたが傾いている場合 あなたがここにそれを得ることができます。 http://dokmanovich.com/Documents/SuperListEvents.zip そうでなければ、私は何かを探していますbetetr pesudoコードと一般的な方向での点より、I以来、私自身でそれを理解しているようには見えません。 50から始まる賞金を提供しています。 – ChadD

答えて

4

Matthewが示唆したように、ラムダ関数を使用しました。ここで

Private Sub btnDynamic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDynamic.Click 

    ListControl1.Columns.Clear() 

    For Each DataCol As DataColumn In _ds.dtbPerson.Columns 
     ' Get the column name in a loop variable - it needs to be in loop scope or this won\'t work properly' 
     Dim colName = DataCol.ColumnName 
     ' Create the function that will be called by the grid' 
     Dim colLambda As ColumnItemValueAccessor = Function(rowItem As Object) General_ItemValueAccessor(rowItem, colName) 
     ' Setup each column in the grid' 
     Dim NewColumn As New BinaryComponents.SuperList.Column(DataCol.ColumnName, DataCol.ColumnName, 220, colLambda) 
     ListControl1.Columns.Add(NewColumn) 
    Next 

End Sub 

Private Function General_ItemValueAccessor(ByVal rowItem As Object, ByVal colName As Object) As Object 
    Dim rowPerson As DataRow = CType(rowItem, DataRow) 
    Return rowPerson.Item(colName).ToString 
End Function 

それがどのように機能するかについて簡単にプライマーです::ここでは動的なアプローチからのコードがある

ラムダ関数は次のようになります各列の新しいコールバック関数を作成してループを通るたびにthis:

Class Func1 
    Dim colName1 As String = "PersonId" 

    Private Function General_ItemValueAccessor1(ByVal rowItem As Object) As Object 
     Dim rowPerson As DataRow = CType(rowItem, DataRow) 
     Return rowPerson.Item(Me.colName1).ToString 
    End Function 
End Class 

Class Func2 
    Dim colName2 As String = "LastName" 

    Private Function General_ItemValueAccessor2(ByVal rowItem As Object) As Object 
     Dim rowPerson As DataRow = CType(rowItem, DataRow) 
     Return rowPerson.Item(Me.colName2).ToString 
    End Function 
End Class 

... for however many columns you have - 3 in this case. 

ループ内でcolName変数が必要で、ラムダで直接DataCol.ColumnNameを使用しないでください。それ以外の場合、グリッドがコールバック関数を呼び出すまでに回ったとき、そのDataCol変数はすべてのコールバック関数のコレクション(またはNothing)の最後の値と等しくなります。

基本的には、これを行うだろうと、あなたが期待したものを取得しません。お役に立てば幸いを

Class Func 
    Dim DataCol1 = DataCol 

    Private Function General_ItemValueAccessor1(ByVal rowItem As Object) As Object 
     Dim rowPerson As DataRow = CType(rowItem, DataRow) 
     Return rowPerson.Item(Me.DataCol1.ColumnName).ToString 
    End Function 

    Private Function General_ItemValueAccessor2(ByVal rowItem As Object) As Object 
     Dim rowPerson As DataRow = CType(rowItem, DataRow) 
     Return rowPerson.Item(Me.DataCol1.ColumnName).ToString 
    End Function 
    ... 

End Class 

。がんばろう。

+0

素晴らしいです、ありがとうございます。それは魅力のように働いた。私はMatthewのクレジットを与えたいと思っていましたが(私は彼の答えを投票しました)、あなたは理解して実際に働くのを助けてくれました。ありがとうございました! – ChadD

1

問題がItemValueAccessor機能のみ行オブジェクトを含む署名を有することであると私はすべての列が同じItemValueAccessor関数にフックアップされたので、必要とされるカラム名を決定する方法を知りませんイベントハンドラとして使用します。

私は過去にそのコントロールを使用していませんでした。私は本当にC#の人です。しかし、各列に新しいlambda functionを作成することで、これを達成できるかもしれないと思います。何かのように:あなたの内部Cc_InternalItemValueAccessorは必要な情報を取得しながら

Private Sub AddCcColumn(ByVal sender As System.Object As System.String) 
    colLambda = (Function(rowItem As Object) Cc_InternalItemValueAccessor(columnName, rowItem)) 
    Dim NewColumn As New BinaryComponents.SuperList.Column("CC", "CC", 110, colLambda) 
    _SuperList.Columns.Add(NewColumn) 
End Sub 

、colLambdaは、署名に適合します。完全にテストされていませんが、基本的な考え方はうまくいくと思います。

+1

Hmmm。私はラムダ式について何か知っているのですが、LINQ(そして匿名の型?返信いただきありがとうございます。 – ChadD

+0

私はLambasが私にそれを食べさせることを理解しているVBの男が必要だと思う。 – ChadD

関連する問題