2

リストからループでいくつかのメニュー項目を作成したいと思います。私はそのようにそれを試しました:

MenuItem mnuItemDepth = new MenuItem();
foreach (ClassDepth depth in ClassDepths.ListOfDepths)
{
    MenuItem it = new MenuItem();
    it.Header = depth.name;
    it.Click += new RoutedEventHandler((s, a) => { ChangeDepth(depth); });
    mnuItemDepths.Items.Add(it);
}

ClassDepths.ListOfDepths の各項目をメニュー項目にする必要があります。それは1つのことを除いて機能します:

クリック イベントは、各メニュー項目に対して同じパラメーター (深さ) で ChangeDepth メソッドをトリガーします。追加された最後のメニュー項目は、リストから作成された各メニュー項目のイベント ハンドラーによって ChangeDepth に渡される深さパラメーターを定義しているようです。誰かが理由を知っていますか?メニュー項目は異なりますが、ChangeDepth は各メニュー項目に対して同じパラメータで呼び出されます。

私の説明がそれほど悪くないことを願っています。ありがとうございました!

4

1 に答える 1

1

これは、クロージャーでループ変数「深さ」をキャプチャすることの問題です。ここで提供できるよりもはるかに優れた説明を読むことができます。このコードを期待どおりに機能させるには、ループ変数をローカル変数にコピーして、代わりに渡します。

MenuItem mnuItemDepth = new MenuItem();
foreach (ClassDepth depth in ClassDepths.ListOfDepths)
{
    var tempDepth = depth;  //capture the loop variable here
    MenuItem it = new MenuItem();
    it.Header = depth.name;
    it.Click += new RoutedEventHandler((s, a) => { ChangeDepth(tempDepth); });
    mnuItemDepths.Items.Add(it);
}
于 2012-10-10T15:01:58.300 に答える