3

ユーザーが選択できるようにする必要があるエンティティの大きなリストがあります。ウィンドウに ContextMenuStrip があり、エンティティのカテゴリごとにいくつかの MenuItem があります。

図書館の例では、「スタッフ」、「借り物」、「利用者」などを考えてみてください...

「職員」には、「雇用形態別」→{「フルタイム」、「パートタイム」}または「性別別」→{「男性」、「女性」}などが含まれる場合があります。

"Borrowables" には "By Type" -> { "Books", "Magazines", "DVDs" } または "By Genre" -> { "Fiction" -> { "Sci-Fi", "Romance", "Crime" を含めることができます" }, "ノンフィクション" { "科学", "音楽", "歴史" } } など.

基本的に、1 つのエンティティが同時に複数の場所に存在する可能性があります。スタッフは正社員で、女性でも構いません。借りられるものは本かもしれませんし、恋愛小説かもしれません。等

List<ToolStripMenuItem>イベントハンドラー、タグ、すべてと一緒にプログラムで作成しました。次に、プログラムでそれぞれを調べ、さまざまなメニューやサブメニューに追加して、さまざまな場所からアクセスできるようにしました。アイデアは、ToolStripMenuItem ごとにメモリ内に 1 つのオブジェクトのみが必要であり、それがチェックされている/チェックされていない場合は、それらすべてに反映される必要があるということです。

これは洗練されたソリューションのように思えますが、それが機能するのを本当に楽しみにしていましたが、ToolStripMenuItem を 1 つの ToolStripMenuItemDropDownItems に追加すると、追加された他の場所から削除されるようです。

これは私を悲しくさせます。それらがすべて同じオブジェクトである場合、チェックされたときに一致するすべてのアイテムを調べてチェックするために多くのコードを書く必要はありません。

最小限のコードでこれを達成できる他の方法はありますか?

これは私が持っているものの小さな例です:

foreach (ToolStripMenuItem item in staffItems)
{
  Staff s = (Staff)item.Tag;

  foreach (ToolStripMenuItem tsmi in byStaffLocationToolStripMenuItem.DropDownItems)
    if ((Location)tsmi.Tag == s.Location)
      tsmi.DropDownItems.Add(item); // [1] Item added here

  foreach (ToolStripMenuItem tsmi in byStaffTypeToolStripMenuItem.DropDownItems)
    if ((StaffType)tsmi.Tag == s.StaffType)
      tsmi.DropDownItems.Add(item); // removed from [1] and added here instead :(
}
4

1 に答える 1

1

それが ControlCollection の機能です。Control から派生したオブジェクトは、同時に 1 つの ControlCollection にのみ存在できます。

あなたのアプローチに従いたい場合は、コマンドに抽象化を導入することをお勧めします(ドラフト):

public interface ICommand
{
    string Name {get;set;}
    bool Enabled { get; set; }
    bool Checked { get; set; }

    void OnClick();
}

次に、ToolStripMenuItem から派生し、ICommand をパラメーターとして取り、それを OnClick で使用する独自のクラスを作成できます。これで、単一のコマンドに対して ICommand を実装する単一のオブジェクトを定義できるはずです。

于 2011-06-17T21:18:31.947 に答える