2012-06-12 38 views
0

我正在嘗試創建一個表單來收集有關項目的信息。有兩種類型:默認項目和特殊項目。項目的字段默認顯示在表單中。Winforms - 如何顯示錶單上項目的額外字段

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

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

如何將SpecialItem的額外字段傳給用戶。

我認爲SpecialItem的字段不應該顯示,直到用戶指出他想通過選擇類型添加特殊項目。

我想使用標籤,顯示額外的字段 的可摺疊式控制的 - 我不知道如果存在的話 隱藏控件和顯示他們在必要時 任何其他的想法

+0

什麼是特定屬性返回類型(例如某種類型的枚舉類型?)和表單控件類型您用於默認項目屬性?使用TableLayoutPanel設計表單並將特殊字段的行設置爲AutoSize會很容易;那麼你可以將與每個特殊屬性相關的控件設置爲'Visible = false'。其他一切都會正常流動。 –

+0

類似的東西...我打算有一個下拉式選擇類型和正確的額外字段將顯示。但Winforms他們增長了嗎? – codingbiz

+0

是的。將行設置爲AutoSize的TableLayoutPanel使用將只使用盡可能多的空間。如果內容不可見,則表格下方的所有內容都會向上移動以填充空白區域;當顯示控件時,表格將在附加字段插入適當位置的情況下進行迴流。這很容易。 –

回答

1

如果兩個類之間有明確的關係,這種關係是非常comprensible到您的用戶,我認爲這是展示各個領域的一件好事。
將所有字段放在groupbox中,併爲Item和SpecialItem類添加兩個選項按鈕。
默認情況下(在表單加載時)Item類將被選中,並且兩個額外的字段被禁用。
如果用戶選擇SpecialItem類選項按鈕,請啓用其他兩個字段。

我在選擇選項時會在許多選項對話框中看到此行爲將啓用其他特定選項。

1

嘗試了這一點 - 它只是反映給定類型,然後將控件放到TableLayoutPanel上添加一些按鈕,然後將兩個事件處理程序綁定到按鈕的單擊事件。這絕不是一個主人,但我認爲會讓你開始。

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

不是一個糟糕的解決方案,如果該類型在構建表單時已知。儘管如此,它並沒有提供基於表單本身的屬性來切換選定的項目類型。 –

+0

公平的觀點...... –

+0

這很好,但我需要一些簡單的東西。 – codingbiz

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(); 
相關問題