2012-01-18 4 views
0

私は以下のことをしたいが、そこには行けません。私はボタンをクリックするたびに、別のデータテーブルにソースを設定したいというフォーム上にdatagridviewを持っています。パラメータを指定して呼び出すメソッドのコレクションを作成する

​​ :次に、各ボタンのクリックに収集することを反復処理

Foo.Add(ta.GetLineItemsByCustomerAndDate(new object[] { "REPT0000", DateTime.Parse("1/18/2012"), 3})); 
Foo.Add(ta.GetLineItemsByDocumentRange(new object[] { "01254785", "01254885", 3 })); 

DynamicsTableAccess ta; 
private void button1_Click(object sender, EventArgs e) 
{ 
    //the DataSource for both calls will be a DataTable 
    //first button click 
    this.dataGridView1.DataSource = ta.GetLineItemsByCustomerAndDate(new object[] { "REPT0000", DateTime.Parse("1/18/2012"), 3}); 
    //second button click 
    this.dataGridView1.DataSource = ta.GetLineItemsByDocumentRange(new object[] { "01254785", "01254885", 3 }); 
    //etc 
} 

は、私は同じように、私のデータベース呼び出しのそれぞれを保持することができ、コレクションのいくつかのタイプを使用する必要があると思います

これはおそらく、可能であれば、ある種のデリゲートが必要になることを認識しています。

これは実動コードで終わるはずのものではないことを認識しています。データベース呼び出しをテストするためにのみ使用しています。私は完全に異なるアプローチに関する提案にはオープンしていますが、ほとんどの場合、この特定の目標を達成するためにFooを構築する方法を探しています。

+0

私は、Webアプリケーションに存在する 'DataBind()'呼び出しの欠如に基づいて、これがクライアントアプリケーションであると仮定しています... – Tejs

+0

ta.GetLineItemsByCustomerAndDateとta.GetLineItemsByDocumentRangeによって返されるデータ型は何ですか?データ表?データセット? –

+0

Tejs correct Chris Shain DataTable – MalibuCusser

答えて

1

私は、ta.GetLineItemsByCustomerAndDateとの両方がDataTableを返すと仮定しています。そうでない場合は、DataTable個のオカレンスを適切なタイプに置き換えてください。

あなたのコードの問題は、上記のメソッドをリストに追加する前にそれらのメソッドを実行しているため、結果をリストに保存するだけです。その代わりに、実行のカプセル化を後で保存する必要があります。後者を達成するために、提案したように、代理人を使用する必要があります。 C#3.5では、代理人を宣言するために必要な構文は、lambda expressionsの導入によりかなり単純化されました。私はあなたがそれらを読むことをお勧めします。

したがって、私たちは最初に、後で実行したいデリゲート(または関数)を保持するためのFooリスト(おそらくクラスインスタンス変数として)を宣言します。

List<Func<DataSet>> Foo = new List<Func<DataTable>>(); 

次に、匿名関数としてカプセル化されたメソッド呼び出しをリストに追加することがあります。 () =>構文は、それに続く文が無名関数としてカプセル化されることに注意してください。 Foo[index] - - と、通常のメソッド呼び出しに関連付けられた()を追加することによって、それを呼び出す

Foo.Add(() => ta.GetLineItemsByCustomerAndDate(new object[] { "REPT0000", DateTime.Parse("1/18/2012"), 3})); 
Foo.Add(() => ta.GetLineItemsByDocumentRange(new object[] { "01254785", "01254885", 3 })); 

は最後に、我々は単にリストから代表団の1への参照を取得する必要があります。

int index = 0; 
private void button1_Click(object sender, EventArgs e) 
{ 
    dt.Clear(); 
    this.dataGridView1.DataSource = Foo[index](); 
    index++; 
} 

編集:でも

var Foo = new List<Func<object[], DataTable>>() 
{ 
    (objs) => ta.GetLineItemsByCustomerAndDate(objs), 
    (objs) => ta.GetLineItemsByDocumentRange(objs), 
}; 

...または、:

List<Func<object[], DataTable>> Foo = new List<Func<object[], DataTable>>(); 
Foo.Add((objs) => ta.GetLineItemsByCustomerAndDate(objs)); 
Foo.Add((objs) => ta.GetLineItemsByDocumentRange(objs)); 

...または、より簡潔に使用して、コレクション初期化子:あなたはあなたにこのような何かを与えているだろうしようとしていた何より簡潔に:

var Foo = new List<Func<object[], DataTable>>() 
{ 
    ta.GetLineItemsByCustomerAndDate, 
    ta.GetLineItemsByDocumentRange, 
}; 

しかし、呼び出されるためには、各無名関数に対応する引数を指定する必要があります。この場合

this.dataGridView1.DataSource = Foo[0](new object[] { "REPT0000", DateTime.Parse("1/18/2012"), 3}); 
this.dataGridView1.DataSource = Foo[1](new object[] { "01254785", "01254885", 3 }); 

、あなたは無名関数の一部として、与えられた引数を含む全体のメソッド呼び出しを、カプセル化しようとしていたので、望ましくないであろうように。そのタイプがFunc<DataTable>であるため返されるタイプがDataTableであるが、何も引数を受け付けていないことを意味しているため、元の無名関数はより完全であったことが分かります。

+0

私はこれらの行に沿って考えていましたが、 'List > Foo =新しいリスト>()'を初めて使用しました。それはうまくいかなかった、ここに来た。ラムダが機能することは分かっていましたが、単純化するだけでした。 – MalibuCusser

+0

これは、 'List >'の逆の方法でしたが、各呼び出しで 'object []'パラメータを指定する必要がありました。 –

+0

@Olivier Jacot-Descombesありがとう、私はあなたの要点を広げた。 – Douglas

1

あなたのごGetLineItemsByDocumentRange方法は次のように定義されていることを仮定:

public DataTable GetLineItemsByDocumentRange(object[] filter) 
{ 
} 

次のようにフィルタを定義します。

List<Func<DataTable>> filters = new List<Func<DataTable>>(); 
filters.Add(() => ta.GetLineItemsByCustomerAndDate(new object[] { "REPT0000", DateTime.Parse("1/18/2012"), 3})); 
filters.Add(() => ta.GetLineItemsByDocumentRange(new object[] { "01254785", "01254885", 3 })); 

フィルタが再評価されます、あなたが

this.dataGridView1.DataSource = filters[index]();  

を呼び出すたびに、現在の顧客を返す。

関連する問題