Mam problem z edycją tekstu w TextBox'ach na formularzu (WindowsForm). Co robię źle i jak to poprawić?
Gdy próbuje dodać tekst, skasować tekst w kontrolce, kontrolka na chwilę przyjmuję zmianę, potem szybko wraca stara wartość (text) przed moją ingerencją i kursor ustawia się na początku tekstu w kontrolce. Najprawdopodobniej miesza tu obsługa zdarzenia TextChanged ale nie mogę dojść w którym momencie. TextChanged ponadto odpala się zaraz gdy faktycznie zmieniam tresc w któryms TextBoxie, przechodzi cała metoda GenerujLogin() i potem znów odpala sie to zdarzenie, nie wiem dlaczego.
Nie do końca rozumiem bindowanie, jak, kiedy i z wywoływaniem jakich zdarzeń dane w BindingSource są aktualizowane i jak, kiedy z BindingSource sa aktualizowane TextBoxy podpiete do BindingSource. Jakby ktoś mógł dopoiwiedzieć.
Po otworzeniu formularza, do TextBox'ów przypisywane są wartości tak:
txtBox_Imie1.DataBindings.Add("Text", WybranyPracownik, "Imie1", false, DataSourceUpdateMode.OnPropertyChanged);
txtBox_Imie2.DataBindings.Add("Text", WybranyPracownik, "Imie2", false, DataSourceUpdateMode.OnPropertyChanged);
txtBox_Nazwisko.DataBindings.Add("Text", WybranyPracownik, "Nazwisko", false, DataSourceUpdateMode.OnPropertyChanged);
txtBox_Login.DataBindings.Add("Text", WybranyPracownik, "Login", false, DataSourceUpdateMode.OnPropertyChanged);
WybranyPracownik jest ustawiany w konstruktorze Okna, Pracownik jest przekazywamy z okna głownego w parametrze konstruktora podokna, a sama właściwość wygląda tak:
public Pracownik WybranyPracownik
{
get
{
return this.pracownikBindingSource.Current as Pracownik;
}
set
{
this.pracownikBindingSource.DataSource = value;
}
}
a samo zdarzenie TextChanged wyglada tak:
private void txtBoxy_ImieniaINazwiska_TextChanged(object sender, EventArgs e)
{
txtBox_Login.Text = GenerujLogin(txtBox_Imie1.Text, txtBox_Imie2.Text, txtBox_Nazwisko.Text);
if (CzyLoginuNieMaWBazie(txtBox_Login.Text))
{
errorProvider.Clear();
}
else
{
errorProvider.SetError(txtBox_Login, "Taki login już występuje w bazie");
}
}
a samo generowanie loginu wygląda tak:
public string GenerujLogin(string imie1, string imie2, string nazwisko)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
if (!string.IsNullOrEmpty(imie1) && !string.IsNullOrEmpty(nazwisko))
{
imie1 = imie1.Trim();
imie1 = imie1.ToLower();
nazwisko = nazwisko.Trim();
nazwisko = nazwisko.ToLower();
imie1 = imie1.First().ToString().ToUpper() + String.Join("", imie1.Skip(1));
nazwisko = nazwisko.First().ToString().ToUpper() + String.Join("", nazwisko.Skip(1));
}
sb.Append(imie1);
sb.Append(" ");
if (!string.IsNullOrEmpty(imie2))
{
imie2 = imie2.Trim();
imie2 = imie2.ToLower();
imie2 = imie2.First().ToString().ToUpper() + String.Join("", imie2.Skip(1));
sb.Append(imie2);
sb.Append(" ");
}
sb.Append(nazwisko);
return sb.ToString();
}
Na tych TextBoxach robie jeszcze walidację od razu podczas wpisywania:
private void txtBox_Imie1_Leave(object sender, EventArgs e)
{
TextBox box = (TextBox)sender;
if (this.CzyPoprawneImie(box.Text))
{
errorProvider.SetError(box, "Pole nie może być puste i dłuższe niż 20 znaków");
}
else
{
errorProvider.Clear();
}
}