C #: enlace de datos de una única clase personalizada para formar controles (casilla de verificación?)
-
05-07-2019 - |
Pregunta
Estoy escribiendo una aplicación de escritorio en Visual Studio 2008 / C #
Terminé (en su mayoría) escribiendo un motor que genera un horario de trabajo para la semana para una pequeña empresa; una forma de un problema de programación de cursos
Ahora mismo estoy diseñando un formulario en el que el usuario puede determinar los parámetros o criterios iniciales para que el motor se adhiera (ya que algunas configuraciones son opcionales)
Tengo una clase llamada EngineParameters, que contiene todas esas configuraciones.
Para el propósito de enlace de datos, creé una clase bndEngineParameters , que encapsula todos los campos relevantes con captadores y definidores
public class bndEngineParameters
{
private engineParameters _parameters;
public bndEngineParameters(engineParameters ep)
{
this._parameters = ep;
}
public bool avoidGrouping
{
get { return _parameters.avoidGrouping; }
set { _parameters.avoidGrouping = value; }
}
public bool avoidWeekends
{
get { return _parameters.avoidWeekends; }
set { _parameters.avoidWeekends = value; }
}
public bool keyFlow
{
get { return _parameters.keyFlow; }
set { _parameters.keyFlow = value; }
}
public bool keyFlowAssistants
{
get { return _parameters.keyFlowAssistants; }
set { _parameters.keyFlowAssistants = value; }
}
}
No está completo: habrá valores int (número máximo de horas que se puede trabajar, etc.); Quiero que esos valores bool estén vinculados a casillas de verificación en mi formulario
Y es en esa tarea trivial donde sorprendentemente me encontré con problemas
Usando " Agregar nueva fuente de datos " asistente, he creado una fuente de enlace
private System.Windows.Forms.BindingSource bndEngineParametersBindingSource;
Luego, vinculé la propiedad Comprobada de mi casilla de verificación a la propiedad correspondiente de mi fuente de enlace:
Implementé una variable local boundParameters para obtener acceso a los parámetros establecidos por el usuario
public partial class formGenerateRota : Form
{
public bndEngineParameters boundParameters;
// (...)
public formGenerateRota()
{
InitializeComponent();
}
private void formGenerateRota_Load(object sender, EventArgs e)
{
boundParameters = new bndEngineParameters(new engineParameters());
bndEngineParametersBindingSource.Add(boundParameters);
}
// (...)
}
¿Y qué? No pasa nada. Hay un objeto bndEngineParameters bajo bndEngineParametersBindingSource.Current (en tiempo de ejecución, por supuesto), pero el valor de AvoidWeekends nunca cambia (cuando activo y desactiva la casilla), y el evento bndEngineParametersBindingSource_CurrentItemChanged nunca se activa
¿Qué pasa?
¡LO SENTIMOS! sí cambia, pero solo después de que la casilla de verificación pierde el foco (después de la validación).
A veces soy estúpido
Si estoy haciendo algo mal de todos modos (no soy bueno con el enlace de datos), ¡lo apreciaría mucho, claro!
Solución
Dos problemas comunes:
- establezca
DataSourceUpdateMode
enOnPropertyChanged
- (opcional) para recibir los cambios desde el objeto, implementar el patrón de evento
{name} Changed
oINotifyPropertyChanged
Sin embargo, para ser honesto, estoy seguro de que la mayor parte de eso no es necesario; solo deberías poder decir:
myCheckbox.Bindings.Add("Checked", myEngineParameters, "avoidWeekends",
false, DataSourceUpdateMode.OnPropertyChanged);
Ejemplo completo:
using System;
using System.Diagnostics;
using System.Windows.Forms;
class EngineParameters {
private bool avoidWeekends;
public bool AvoidWeekends {
get { return avoidWeekends; }
set {
avoidWeekends = value;
Debug.WriteLine("AvoidWeekends => " + value);
}
}
}
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
using(Form form = new Form())
using (CheckBox myCheckbox = new CheckBox()) {
EngineParameters myEngineParameters = new EngineParameters();
myEngineParameters.AvoidWeekends = true;
form.Controls.Add(myCheckbox);
myCheckbox.DataBindings.Add("Checked", myEngineParameters, "AvoidWeekends",
false, DataSourceUpdateMode.OnPropertyChanged);
Application.Run(form);
}
}
}
Otros consejos
En lugar de esto:
bndEngineParametersBindingSource.Add(boundParameters);
haz esto:
bndEngineParametersBindingSource.DataSource = boundParameters;