0

アイテムに関する情報を収集するためのフォームを作成しようとしています。デフォルトアイテムとスペシャルアイテムの2種類があります。アイテムのフィールドは、デフォルトでフォームに表示されます。

public class Item
{
   Id
   Name
   Quantity
   Type //default, special
}

public class SpecialItem : Item //inherits from item
{
   //extra fields here
   ExpiryDate
   SafeForChildren
}

SpecialItem の追加フィールドをユーザーに渡すにはどうすればよいですか。

ユーザーがタイプを選択して特別なアイテムを追加したいことを示すまで、 SpecialItem のフィールドは表示されるべきではないと思います。

タブを使用して追加のフィールドを表示することを考えています 折りたたみ可能なコントロール - これが存在する場合は必要ありません コントロールを非表示にし、必要に応じて表示する その他のアイデア

4

3 に答える 3

1

これを試してみてください。指定されたタイプを反映し、コントロールをTableLayoutPanelいくつかのボタンに配置し、2 つのイベント ハンドラーをボタンのクリック イベントにバインドします。決してマスターピースではありませんが、始めるきっかけになると思います。

public MyForm(Type typeToDisplay)
        {
            InitializeComponent();

            PropertyInfo[] settableProperties = typeToDisplay.GetProperties(BindingFlags.Instance | BindingFlags.Public);

            TableLayoutPanel panel = new TableLayoutPanel();
            panel.ColumnCount = 2;
            panel.RowCount = settableProperties.Length+1;
            panel.Name = "LayoutPanel";
            this.Controls.Add(panel);

            int rowIndex = 0;

            foreach (PropertyInfo info in settableProperties)
            {
                Label propLabel = new Label();
                propLabel.Text = info.Name;

                TextBox propField = new TextBox();

                panel.Controls.Add(propLabel, 0, rowIndex);
                panel.Controls.Add(propField, 1, rowIndex);

                rowIndex++;
            }

            panel.Controls.Add(new Button() { Text = "OK", Name="OK" }, 0, rowIndex);
            panel.Controls.Add(new Button() { Text = "Cancel", Name="Cancel" }, 1, rowIndex);

            panel.Controls["Cancel"].Click += new EventHandler(CloseForm);
            panel.Controls["OK"].Click += new EventHandler(SaveChanges);

            panel.Height = this.Height;
            panel.Width = this.Width;

        }

        private void CloseForm(object sender, EventArgs e)
        {
            this.Close();
        }

        private void SaveChanges(object sender, EventArgs e)
        {
            MessageBox.Show("Save changes was clicked!");
            this.Close();
        }
于 2012-06-12T20:57:41.987 に答える
1

2 つのクラスの間に明確な関係があり、この関係がユーザーによく理解できる場合、すべてのフィールドを表示するのは良いことだと思います。
グループボックス内にすべてのフィールドを配置し、Item クラスと SpecialItem クラスの 2 つのオプション ボタンを追加します。
デフォルトでは (フォームの読み込み時)、Item クラスが選択され、2 つの追加フィールドは無効になっています。
ユーザーが SpecialItem クラスのオプション ボタンを選択した場合は、他の 2 つのフィールドを有効にします。

オプションを選択すると他の特定のオプションが有効になる場合、多くのオプション ダイアログでこの動作を確認しました。

于 2012-06-12T20:59:01.180 に答える
1

上記の私の提案を示す完全なソリューションの例を次に示します。これはすべてコードで行われ、単一の列のみを使用しますが、デザイナーが作成したコントロール (もちろん) や複数の列でも機能することに注意してください。Visible = false未使用の行が適切に折りたたまれるように、行内のすべてのコントロール (たとえば、ラベルとそれに対応する入力コントロール) を必ず設定してください。

TableLayoutPanel tlp = new TableLayoutPanel();
tlp.RowStyles.Add(new RowStyle(SizeType.Absolute, 25));
tlp.RowStyles.Add(new RowStyle(SizeType.Absolute, 25));
tlp.RowStyles.Add(new RowStyle(SizeType.Absolute, 25));
tlp.RowStyles.Add(new RowStyle(SizeType.Absolute, 25));
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tlp.RowStyles.Add(new RowStyle(SizeType.Absolute, 25));

TextBox b1 = new TextBox(); b1.Dock = DockStyle.Fill;
TextBox b2 = new TextBox(); b2.Dock = DockStyle.Fill;
TextBox b3 = new TextBox(); b3.Dock = DockStyle.Fill;
CheckBox special = new CheckBox(); special.Text = "Special?";
TextBox b4 = new TextBox(); b4.Dock = DockStyle.Fill; b4.Visible = false;
TextBox b5 = new TextBox(); b5.Dock = DockStyle.Fill; b5.Visible = false;
Button button = new Button(); button.Text = "Save";

special.CheckedChanged += new EventHandler((sender, args) => { b4.Visible = b5.Visible = special.Checked; });

tlp.Controls.Add(b1, 0, 0);
tlp.Controls.Add(b2, 0, 1);
tlp.Controls.Add(b3, 0, 2);
tlp.Controls.Add(special, 0, 3);
tlp.Controls.Add(b4, 0, 4);
tlp.Controls.Add(b5, 0, 5);
tlp.Controls.Add(button, 0, 6);

Controls.Add(tlp);
tlp.Dock = DockStyle.Fill;
tlp.BringToFront();
于 2012-06-12T21:20:11.850 に答える