Winforms: cómo mostrar campos adicionales de un elemento en un formulario
Frecuentes
Visto 277 equipos
0
Estoy tratando de crear un formulario para recopilar información sobre un artículo. Hay dos tipos: elemento predeterminado y elemento especial. Los campos del elemento se muestran en el formulario de forma predeterminada.
public class Item
{
Id
Name
Quantity
Type //default, special
}
public class SpecialItem : Item //inherits from item
{
//extra fields here
ExpiryDate
SafeForChildren
}
¿Cómo llevaré los campos adicionales de SpecialItem al usuario?
Creo que los campos de SpecialItem no deberían mostrarse hasta que el usuario indique que desea agregar un elemento especial seleccionando el tipo.
Pienso en usar una pestaña para mostrar campos extra Un control colapsable - No sé si esto existe Ocultar los controles y mostrarlos cuando sea necesario Cualquier otra idea
3 Respuestas
1
Si las dos clases tienen una relación clara entre ellas y esta relación es bien comprensible para su usuario, creo que es bueno mostrar todos los campos.
Coloque todos los campos dentro de un cuadro de grupo y agregue dos botones de opción para la clase Item y SpecialItem.
De forma predeterminada (al cargar el formulario), se seleccionará la clase de elemento y los dos campos adicionales estarán deshabilitados.
Si el usuario elige el botón de opción de clase SpecialItem, habilite los otros dos campos.
He visto este comportamiento en muchos cuadros de diálogo de opciones cuando seleccionar una opción habilitará otras opciones específicas.
Respondido el 12 de junio de 12 a las 21:06
1
Pruebe esto: simplemente refleja el tipo dado y luego coloca los controles en un TableLayoutPanel
agrega un par de botones y luego vincula dos controladores de eventos al evento de clic de los botones. De ninguna manera es una obra maestra, pero creo que lo ayudará a comenzar.
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();
}
Respondido el 12 de junio de 12 a las 21:06
No es una mala solución, si el tipo se conoce cuando se crea el formulario. Sin embargo, no permite cambiar el tipo de elemento seleccionado en función de una de las propiedades del formulario en sí. - Domingo P
1
Aquí hay una solución de ejemplo completa para demostrar mi sugerencia anterior. Tenga en cuenta que todo está hecho en código y usa solo una columna, pero también puede funcionar con controles producidos por diseñadores (por supuesto) y varias columnas. Solo asegúrese de configurar todos los controles en una fila (por ejemplo, una etiqueta y su control de entrada correspondiente) para Visible = false
para que las filas no utilizadas se colapsen correctamente.
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();
Respondido el 12 de junio de 12 a las 22:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c# winforms user-interface or haz tu propia pregunta.
¿Cuáles son los tipos de devolución de propiedad específicos (por ejemplo, algún tipo de enumeración para Tipo) y los tipos de control de formulario que está utilizando para las propiedades predeterminadas del Elemento? Sería bastante fácil diseñar su formulario con un TableLayoutPanel con las filas para los campos especiales establecidos en AutoSize; entonces podría establecer los controles asociados con cada propiedad especial para
Visible = false
. Todo lo demás fluirá correctamente. - Dominic Palgo así... planeo tener un menú desplegable donde seleccione el tipo y se mostrarán los campos adicionales correctos. pero Winforms ¿crecen? - codingbiz
Si. El uso de un TableLayoutPanel con filas configuradas en AutoSize usará solo el espacio necesario. Si el contenido es invisible, todo lo que está debajo de él en la tabla se moverá hacia arriba para llenar el espacio vacío; cuando se muestran los controles, la tabla volverá a fluir con los campos adicionales insertados en la ubicación adecuada. Es muy fácil. - Dominic P