C #: ligação de dados uma única classe personalizada para controles de formulário, (caixa?)
-
05-07-2019 - |
Pergunta
Eu estou escrevendo um aplicativo de desktop em Visual Studio 2008 / C #
Eu terminei (a maioria) escrevendo um motor que gera um cronograma de trabalho para a semana para uma pequena empresa; uma forma de um problema curso de programação
Agora eu estou projetando um formulário no qual o usuário pode determinar os parâmetros iniciais, ou critérios, para o mecanismo de aderir a (como algumas configurações são opcionais)
Eu tenho uma classe chamada EngineParameters, que detém todas essas configurações.
Para efeitos de ligação de dados, criei um bndEngineParameters classe, que encapsula todas as áreas relevantes com getters e setters
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; }
}
}
Não é completa - haverá valores int (número máximo de horas pode-se trabalhar etc.); Eu quero esses valores bool estar vinculado a caixas de seleção no meu formulário
E é nessa tarefa trivial onde eu correu surpreendentemente problemas
Usando o assistente "Novo DataSource Adicionar", eu criei uma fonte de ligação
private System.Windows.Forms.BindingSource bndEngineParametersBindingSource;
Eu, então, obrigado a verificado propriedade de meu caixa de seleção para a respectiva propriedade de minha fonte de ligação:
Eu implementei uma variável local boundParameters para que eu obter um acesso aos parâmetros definidos pelo usuário
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);
}
// (...)
}
E o quê? Nada acontece. Há uma bndEngineParameters objeto em bndEngineParametersBindingSource.Current (em tempo de execução é claro), mas o avoidWeekends valor nunca muda (quando eu verificar a caixa de seleção dentro e fora), e bndEngineParametersBindingSource_CurrentItemChanged evento nunca é disparado
O que há de errado?
Sorry! ele faz a mudança, mas só depois de a caixa perde o foco (após validação).
Eu sou às vezes estúpidas
Se eu estou fazendo algo errado de qualquer maneira (eu não sou boa com ligação de dados), eu apreciaria muito se você mencionar isso, é claro!
Solução
Duas questões comuns:
- definir o
DataSourceUpdateMode
paraOnPropertyChanged
- (opcional) para receber alterações de o objeto, implementar o padrão evento
{name}Changed
ouINotifyPropertyChanged
Para ser honesto embora, tenho certeza que a maioria de que não é necessário; você deve apenas ser capaz de dizer:
myCheckbox.Bindings.Add("Checked", myEngineParameters, "avoidWeekends",
false, DataSourceUpdateMode.OnPropertyChanged);
exemplo completa:
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);
}
}
}
Outras dicas
Em vez disso:
bndEngineParametersBindingSource.Add(boundParameters);
fazer isso:
bndEngineParametersBindingSource.DataSource = boundParameters;