Witajcie.
Na wstępie errata dotycząca klasy z poprzedniej części:
Chodzi mianowicie o MySqlDB.cs.
W updateRow i createRow wykorzystałem nazwę pola name natomiast tabela zamiast tego posiada nazwę service. Należy zmienić błędną wartość. Poprzedni artykuł został już zaktualizowany.
W tej części naszych zmagań z aplikacją do przechowywania naszych haseł zajmiemy się obsługą DataGridView czyli następującymi tematami:
- konfiguracja DataGridView,
- uwzględnianie filtru nazwy,
- dodawanie wpisów,
- edycja wpisu,
- usuwanie wpisów,
Konfiguracja DataGridView
Zaczynamy więc od konfiguracji naszego DataGridView nazwanego w ramach zeszłego artykułu dataGridViewPasswords. Aby dokonać edycji kolumn naciskamy prawym przyciskiem myszy na nasze dataGridView i wybieramy Edit Columns… .
Dodawanie poszczególnych kolumn następuje po wciśnięciu Add….
Moje propozycje względem jego prawidłowego zachowania i wyświetlania są następujące:
W kodzie (o ile wcześniej nie było zmienione zmieniamy dataGridViewPasswords.AutoGenerateColumns = true na false.
Dla spokoju warto jest sprawdzić, czy nasza aplikacja dalej wyświetla dane z tabeli czyli Debug. Jeżeli wszystko jest ok to przechodzimy do kolejnego punktu.
Uwzględnianie filtru nazwy
Mamy tabelę, więc teraz zajmiemy się filtrem.
Aby zabezpieczyć naszą aplikację przed zwiechą, musimy ustalić sztywne bariery możliwych do wpisywania znaków, które będą wpisywane w pole szukania. Moim ulubionym sposobem jest wykorzystanie zdarzenia KeyPress.
Zaznaczamy nasze pole tekstowe (jeżeli wcześniej nie zmieniliśmy zmieńmy jego wartość „Name” na textBoxServiceFilter) i przechodzimy w Properties na zdarzenia. W zdarzeniach znajdźmy event KeyPress i w puste pole po prawej stronie tzw. 2-klikiem przechodzimy na kod bezpośrednio do składni eventu.
Nasza metoda będzie wyglądała mniej więcej tak:
private void textBoxServiceFilter_KeyPress(object sender, KeyPressEventArgs e) { e.Handled = !((char.IsLetter(e.KeyChar) || char.IsNumber(e.KeyChar) || char.IsWhiteSpace(e.KeyChar)) || e.KeyChar == (char)Keys.Back); }
Powyższy kod ogranicza nam wpisywanie znaków do liter, numerów, spacji i backspace.
Teraz zrealizujemy naszą funkcję filtrującą:
Na pierwszy ogień pójdzie nasza metoda refreshPasswordsTable(). Musimy dodać linię, która będzie Filtrowała nasze wiersze. Do takich zadań służy Właściwość DataView zwana RowFilter.
Nasza metoda będzie wyglądała tak
private void refreshPasswordsTable() { dataGridViewPasswords.DataSource = null; dataGridViewPasswords.Rows.Clear(); MySqlDB mySql = new MySqlDB(); DataSet passwordsDataSet = mySql.readRows(); DataTable passwordsDataTable = passwordsDataSet.Tables[0]; DataView passwordsDataView = new DataView(passwordsDataTable); dataGridViewPasswords.AutoGenerateColumns = false; if (textBoxServiceFilter.Text.Length > 0) { passwordsDataView.RowFilter = "service like '%" + textBoxServiceFilter.Text + "%'"; } dataGridViewPasswords.DataSource = passwordsDataView; }
Wystarczy już tylko dodać odświeżanie tabeli za każdym razem kiedy zmieni się tekst w naszym polu tekstowym.
Poszukajmy w zdarzeniach dla textBoxServiceFilter eventu TextChange, 2-klikiem przechodzimy do kodowania i wpisujemy:
private void textBoxServiceFilter_TextChanged(object sender, EventArgs e) { refreshPasswordsTable(); }
Testujemy aplikację poprzez Debug. Jeżeli aplikacja się uruchamia i filtr działa wiedz że coś się dzieje 🙂 ale tak czy inaczej wszystko gra i przechodzimy dalej.
Teraz zrealizujemy kolejny punkt a właściwie punkty.
Dodawanie wpisów
Edycja wpisów
Aby zrealizować dodawanie i edycję musimy dodać nową formatkę.
Zachowujemy się tak jak wcześniej gdy dodawaliśmy nowe klasy tylko tym razem wybieramy zamiast Class – Windows Form i nazywamy go np. FormPassword.
Z Toolboxa dodajemy do niego 2 x TextBox, 1 x RichTextBox i 3 x Label oraz 2 x Button.
Dwa pola textBox nazwiemy sobie textBoxService i textBoxValue, pole richTextBox nazwiemy richTextBoxNote. W label możemy zmienić tylko pole text, tak aby dotyczyły poszczególnych pól tekstowych (patrz grafika).
Przyciski nazwijmy buttonCancel – text Anuluj i buttonSave – text Zapisz.
W kodzie dla formatki musimy przewidzieć 2 sytuacje. Pierwsza – dodawanie a druga edycja.
Dobrym sposobem na to będzie wykorzystanie argumentu, z którym będzie odpalana nasza nowa formatka. W klasie public FormPassword() w nawiasie wpisujemy int passwordId a Cały kod głównej klasy w tym momencie wygląda tak.
public partial class FormPassword : Form { public int passwordId; MySqlDB mySql; //ułatwiamy sobie życie, aby nie inicjować za każdym razem tej klasy. public FormPassword(int passwordId = -1) //w przypadku braku argumentu zostanie przypisana wartość -1 { InitializeComponent(); this.passwordId = passwordId; mySql = new MySqlDB(); } }
Aby możliwe było edytowanie musimy jeszcze mieć możliwość wyciągania pojedynczego rekordu.
Tworzymy więc sobie metodę w klasie MySqlDB.cs jak poniżej:
public DataSet readRow(int id) { connection.Open(); MySqlDataAdapter dataAdapterReadOne = new MySqlDataAdapter(); MySqlCommand commandReadOne = new MySqlCommand(); commandReadOne.Connection = connection; commandReadOne.CommandText = "select * from passwords WHERE id = @id "; commandReadOne.Parameters.Add(new MySqlParameter("id", id)); dataAdapterReadOne.SelectCommand = commandReadOne; DataSet dataSetForRead = new DataSet(); dataAdapterReadOne.Fill(dataSetForRead); connection.Close(); connection.Dispose(); return dataSetForRead; }
Teraz ustawmy zdarzenie Load dla naszej nowej formatki.
private void FormPassword_Load(object sender, EventArgs e) { if (passwordId > 0) { DataSet dataSetRow = mySql.readRow(passwordId); //inicjujemy readRow z klasy MySqlDB DataTable dataTableRow = dataSetRow.Tables[0]; //wczytujemy dane do tabeli textBoxService.Text = dataTableRow.Rows[0][1].ToString(); //przypisujemy zmienną do pola tekstowego textBoxValue.Text = dataTableRow.Rows[0][2].ToString(); //przypisujemy zmienną do pola tekstowego richTextboxNote.Text = dataTableRow.Rows[0][3].ToString(); //przypisujemy zmienną do bogatego :) pola tekstowego } }
Zauważmy, że w przypadku podania passwordId program zaczyta nam dane z bazy.
W przeciwnym razie nic nie wczyta i formatka będzie czysta niczym do edycji dla dodania nowego rekordu.
Wieńcząc dzieło dla formatki dodamy jeszcze zdarzenia tj. buttonCancel_Click, buttonSave_Click oraz metodę dla walidacji.
Metoda walidacji będzie wyglądała np tak:
private bool validation() { bool validatonResoult = false; if (textBoxService.Text.Length > 0 && textBoxValue.Text.Length > 0) validatonResoult = true; else validatonResoult = false; return validatonResoult; }
Oczywiście może wyglądać inaczej, zgodnie z życzeniem projektanta kodu ale do podstawowej zasady (wynikającej z wypełniania bazy danych) wystarczy.
Event buttonCancel_Click nie będzie krył żadnych rewolucji :
private void buttonCancel_Click(object sender, EventArgs e) { this.Close(); //zamyka to - czyli nasze okno }
Natomiast ciekawiej będzie wyglądało 2 zdarzenie:
private void buttonSave_Click(object sender, EventArgs e) { if (validation()) //jeżeli walidacja jest spełniona { if (passwordId > 0) //jeżeli był wczytany rekord { mySql.updateRow(passwordId, textBoxService.Text, textBoxValue.Text, richTextboxNote.Text); } else //a jeżeli nie był to { mySql.createRow(textBoxService.Text, textBoxValue.Text, richTextboxNote.Text); } this.Close(); //zamykamy okienko } else //nie spełnienie walidacji musi kończyć się spektakularnie jakimś MessageBox-em { MessageBox.Show("Wstawiłeś coś nie tak. Pola Serwis i Wartość muszą być wypełnione"); } }
Szybkość tego rozwiązania zawdzięczamy wcześniejszemu przygotowaniu metod w klasie MySqlDB tj. updateRow i createRow
Wracamy do głównej formatki:
Zaprogramujmy więc nasze przyciski Dodaj i Edytuj.
Aby dodać event dodawania wchodzimy w naszą formatkę i dla przycisku Dodaj robimy na nim 2-klik. W metodzie buttonAdd_Click musimy wstawić:
private void buttonAdd_Click(object sender, EventArgs e) { using (FormPassword passwordAdd = new FormPassword()) //tworzymy nową intancję klasy FormPassword { passwordAdd.ShowDialog(); // pokazujemy klasę - formatkę } refreshPasswordsTable(); //odświeżamy }
Tak samo z przyciskiem Edytuj. W zdarzeniu buttonEdit_Click wpisujemy
private void buttonEdit_Click(object sender, EventArgs e) { if (dataGridViewPasswords.SelectedRows.Count > 0) { using (FormPassword passwordAdd = new FormPassword(int.Parse(dataGridViewPasswords.CurrentRow.Cells["PasswordId"].Value.ToString()))) //tworzymy nową intancję klasy FormPassword ale tym razem wczytujemy do niej Id który jest ukryty w najszej tabeli { passwordAdd.ShowDialog(); // pokazujemy klasę - formatkę } } refreshPasswordsTable(); //odświeżamy }
Usuwanie wpisów
Zróbmy jeszcze usuwanie rekordów aby wykonać wszystkie zmiany w tej formatce zaplanowane w tej części.
W buttonRemove_Click wpisujemy :
if (dataGridViewPasswords.SelectedRows.Count > 0) { MySqlDB mySql = new MySqlDB(); mySql.deleteRow(int.Parse(dataGridViewPasswords.CurrentRow.Cells["PasswordId"].Value.ToString())); refreshPasswordsTable(); }
Aby program działał w 100 % potrzebny mu w tabeli dataGrid uchwyt typi Row a nie jak teraz Cell. Zmienimy więc sposób zaznaczenia.
W Propierties dla dataGridViewPassword zmieniamy : MultiSelect na False oraz SelectionMode na FullRowSelect.
Teraz musimy jeszcze zakończyć prace w naszej formatce FormPassword.
Dla przycisku buttonCancel ustawiamy zdarzenie Click i w metodzie wpisujemy : this.Close();
To było łatwe, prawda ?
Teraz będzie trochę trochę turniej
private void buttonRefresh_Click(object sender, EventArgs e) { refreshPasswordsTable(); }
To by było na tyle. Sprawdźcie jeszcze czy wasza aplikacja odpala i do zobaczenia w 3 ostatniej części.
Finalnie aplikacja winna wyglądać tak:
Przynajmniej na tym etapie.
W następnej części zrobimy:
- logowanie,
- wykorzystamy szyfrowanie danych,
- schowamy naszą aplikację do tray-a.
- dodamy ikonki i zrobimy wianek.