Winforms - 如何在表单上显示项目的额外字段

本文关键字:项目 字段 显示 表单 Winforms | 更新日期: 2023-09-27 18:37:08

我正在尝试创建一个表单来收集有关项目的信息。有两种类型:默认项目和特殊项目。默认情况下,项目的字段显示在表单上。

public class Item
{
   Id
   Name
   Quantity
   Type //default, special
}
public class SpecialItem : Item //inherits from item
{
   //extra fields here
   ExpiryDate
   SafeForChildren
}

我将如何将特殊项目的额外字段带给用户。

我认为在用户指示他想通过选择类型添加特殊项目之前,SpecialItem 的字段不应该显示。

我想使用选项卡来显示额外的字段可折叠控件 - 如果存在,我不知道隐藏控件并在必要时显示它们任何其他想法

Winforms - 如何在表单上显示项目的额外字段

如果这两个类之间有明确的关系,并且这种关系对你的用户来说是很好的理解,我认为显示每个字段是一件好事。
将所有字段放在分组框中,并为 Item 和 SpecialItem 类添加两个选项按钮。
默认情况下(在表单加载时),将选择 Item 类,并禁用两个额外的字段。
如果用户选择"特殊项类"选项按钮,请启用其他两个字段。

当选择一个选项将启用其他特定选项时,我已经在许多选项对话框中看到了这种行为。

试试这个 - 它只是反映给定的类型,然后将控件放在一个TableLayoutPanel上,添加几个按钮,然后将两个事件处理程序绑定到按钮的 click 事件。这绝不是杰作,但我认为会让你开始。

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();
        }

这是一个完整的示例解决方案,用于演示我上面的建议。请注意,它全部在代码中完成,仅使用单个列,但也可以使用设计器生成的控件(当然)和多个列。只需确保将一行中的所有控件(例如,标签及其相应的输入控件)设置为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();
相关文章: