Programowanie w MS Visual Studio 2005 z wykorzystaniem MS

Transkrypt

Programowanie w MS Visual Studio 2005 z wykorzystaniem MS
Programowanie w MS Visual Studio 2005 z
wykorzystaniem MS SQL Server 2005
Lekcja 4
 Multizaznaczanie programowe
 Używanie filtrów (ukrywanie kolumn i wierszy)
 Zapisywanie danych z DataSet do pliku *.XML
 Tworzenie widoku master-detail
Wymagania:
 Wymagania z poprzednich lekcji
 Projekt z lekcji 3
 15 minut wolnego czasu
UWAGA – Wszystkie poniższe przykłady są robione na tabeli Pracownik, częśd z tych przykładów może nie
działad na innych tabelach, trzeba będzie wtedy dokonad modyfikacji, które zostawiam czytelnikowi jako
proste dwiczenie .
1. Multizaznaczanie programowe:
Czasami, gdy nasza bazy jest strasznie duża wyszukiwanie w niej określonej wartości trwa
wieki. Postaramy się teraz napisad coś co ułatwi nam tą czynnośd.
Zacznijmy od dodania do naszej formy pola tekstowego, które posłuży nam jako mała
wyszukiwarka! Dodajmy też przycisk filtr – będzie on potrzebny w przyszłości. W ustawieniach
naszego pola tekstowego kliknijmy na żółty piorun i odnajdźmy tam event TextChanged i go
utwórzmy, a do jego środka wpiszmy:
try
{
// odznaczamy bierzący wiersz jezeli jest zaznaczony
if (!(dataGridView1.CurrentRow ==null))
{
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Selected =
false;
}
// ustawiamy opcje by nasz DataGrid mógł zaznaczyć wiele wierszy
dataGridView1.MultiSelect = true;
// zaczynamy przeszukiwać
for (int i = 0; i != dataGridView1.Rows.Count; i++)
{
// jeśli zaznaczony to odznacz --> zapobiega probie ponownego
zaznaczenia wiersza
dataGridView1.Rows[i].Selected = false;
for (int j = 0; j != dataGridView1.ColumnCount; j++)
{
// sprawdzamy czy aktualny wiersz posiada szukana wartosc
// zmniejszamy obydwa stringi gdyz duże i małe litery są
rozróżnialne
if(dataGridView1.Rows[i].Cells[j].Value.ToString().ToLower()
.Contains(toolStripTextBox1.Text.ToLower()))
{
// jeśli posiada to "zapalamy" wiersz
dataGridView1.Rows[i].Selected = true;
}
}
}
}
catch (Exception z)
{
// łapiemy bład
MessageBox.Show( z.Message, "\nBLAD");
}
Teraz uruchommy nasz program i zobaczmy, jakie są efekty. Jeśli wszystko poszło dobrze
okno powinno teraz tak wyglądad:
2. Używanie filtrów (ukrywanie kolumn i wierszy):
I.
Większośd baz danych posiada kolumny z prywatnymi informacjami, takie kolumny można ukryd, by
dane w nich zawarte nie wpadły w niepowołane ręce lub by pozbyd się nadmiarowych informacji,
które są nie potrzebne koocowemu użytkownikowi. W naszej bazie taką kolumną może byd id
pracowników.
Pierwsze, co należy zrobid to dodad zmienną globalną:
private BindingSource bindingSource1 = new BindingSource();
Następnie starą metodę DataGridFill() należy zmienid na:
private void DataGridFill()
{
/// sciezka do naszej bazy
string path = openFileDialog1.FileName.ToString();
/// polecenie polaczenia jakie wyslemy do Serwera
string connectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename="
+ path + ";Integrated Security=True;User Instance=True";
/// komenda select ktora wykona baza
string commandString = textBox1.Text;
/// nazwa tabeli ktora wyswietlimy
try
{
SqlConnection connection = new SqlConnection(connectionString);
/// SqlDataAdapter wyciaga z bazy na ktora "wskazuje" polaczenie
//rekordy ktore zwraca sa wynikiem commandString
DataAdapter = new SqlDataAdapter(commandString , connection);
/// Dodajemy do DataSet.Tables tabele o nazwie tableName
DataAdapter.Fill(dataSet1,"show");
/// zamykamy polaczeniem z baza
connection.Close();
/// jako zrodlo danych (DataSource) naszego BindingSource-a podajemy
//tabele z wypelnionego przed chwila dataseta
bindingSource1.DataSource = dataSet1.Tables[0];
//i dopiero teraz dajemy naszemu datagridoView zrodlo danych jako
nasz BindingSource
dataGridView1.DataSource = bindingSource1;
//ustawiamy niewidoczną kolumne
dataGridView1.Columns["ID"].Visible = false;
}
catch (Exception ex)
{
/// Jesli cos pojdzie nie tak np. zla nazwa tabeli, zla sciezka do bazy
/// wyswitli nam sie MessageBox z bledem
MessageBox.Show("Wyjatek : " + ex.Message, "BŁAD");
}
}
Po włączeniu i wczytaniu bazy powinniśmy posiadad tak wyglądający formularz:
II. Jeśli nasza baza posiada ponad tysiąc wierszy - to metoda z multizaznaczaniem staje się całkowicie
nieprzydatna, w takich przypadkach dużo lepszym rozwiązaniem byłoby ukrycie wierszy, które dla
nas są nieistotne. Z pomocą przyjdzie nam narzędzie BindingSource a konkretniej jego opcja
filtrowania!
Utwórzmy teraz akcję dla kliknięcia na przycisk filtr:
private void filt_Click(object sender, EventArgs e)
{
try
{
// zmienna potrzebna do zapoczątkowania stringa filtru
bool raz = false;
// jesli wczesniej był jakiś filtr to go sciągamy
bindingSource1.RemoveFilter();
// string w którym bedzie kąmęda filtru
string filtr = "";
// analogicznie do metody mulizaznaczenia
if (!(dataGridView1.CurrentRow == null))
{
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Selected =
false;
}
dataGridView1.MultiSelect = true;
for (int i = 0; i != dataGridView1.Rows.Count-1; i++)
{
dataGridView1.Rows[i].Selected = false;
for (int j = 0; j != dataGridView1.ColumnCount; j++)
{
if
(dataGridView1.Rows[i].Cells[j].Value.ToString().ToLower().C
ontains(toolStripTextBox1.Text.ToLower()))
{
dataGridView1.Rows[i].Selected = true;
if (raz == false)
{
// zaczynamy wpisywac ID pracowników którzy
pasują do naszego filtra
filtr += "ID='" +dataGridView1.Rows[i].Cells
["ID"].Value.ToString() + "'";
raz = true;
}
else
// dopisujemy kolejnego pracownika
filtr += "OR ID='" + dataGridView1.Rows[i].
Cells["ID"].Value.ToString()+ "'";
}
}
}
// nakładamy filtr na tabele
bindingSource1.Filter = filtr;
toolStripTextBox1.Text = "";
}
catch (Exception z)
{
// łapiemy bład
MessageBox.Show(z.Message, "\nBLAD");
}
}
W ten oto prosty sposób używa się filtrowania tabeli!
3. Zapisywanie zawartości DataSet do pliku *.xml
Jeśli chcemy opublikowad nasze dane na np. stronie internetowej lub posłużyd się nimi w jakimś
innym programie, który nie będzie mógł odczytywad danych z bazy, bardzo przydatną opcją jest zapisanie
takich danych do jednego z najbardziej uniwersalnych rodzajów plików jakim jest *.xml. W bardzo prosty
sposób dane z pliku *.xml można przenosid, edytowad lub wykorzystywad w innych programach (zachęcam
do zapoznania się bliżej z tym formatem). Teraz pokażemy jak w prosty i szybki sposób zapisad dane przez
nas wyświetlone, właśnie do pliku *.xml.
Dodajmy nowy przycisk na naszą formę i dajmy mu nazwę Zapisz do XML oraz z menu Toolbox
dodajmy SaveFileDialog. Zróbmy tak by przycisk wykonywała taki kod:
private void ZapiszDoXML_Click(object sender, EventArgs e)
{
try
{
//uruchamiamy dialog zapisu
saveFileDialog1.ShowDialog();
foreach (DataTable dt in dataSet1.Tables)
{
foreach (DataColumn dc in dt.Columns)
{
// zmieniamy mapowanie - ta opcja jest przykładowa bez tego
// zapisanie też zadziała, ale moim zdaniem bedzie troche
// mniej czytelne
dc.ColumnMapping = MappingType.Attribute;
}
}
// zapisujemy
dataSet1.WriteXml(saveFileDialog1.FileName+ ".xml",
XmlWriteMode.WriteSchema);
}
catch (Exception z)
{
// łapiemy bład
MessageBox.Show(z.Message, "\nBLAD");
}
}
Gotowe! Teraz nie grozi nam już mozolne włączanie i wyłączanie programu, gdy popełnimy błąd 
4. Tworzenie widoku Master-Detail
Na koniec dzisiejszej lekcji chciałbym nauczyd Ciebie jeszcze jednej bardzo przydatnej rzeczy – tworzenia
widoku Master-Detail. Co to jest ten widok? Już spieszę z odpowiedzią- mianowicie jest to wyświetlanie tak
danych, że jeśli po jednej stronie widad spis nadrzędnych elementów, a po drugiej są szczegółowe informacje
odnoszące się do jednego z tych elementów. Gdy zmieniamy zaznaczenie w spisie elementów nadrzędnych
automatycznie zmieniają nam się dane na odpowiednie w widoku szczegółowym.
Postarajmy się teraz stworzyd w naszym programie taki widok. Jako elementy nadrzędne weźmiemy spis
pracowników, podrzędnymi natomiast będą zadania należące do poszczególnych osób z naszej bazy. Na początku
dodajmy nowy DataGridView na naszą formatkę. Dodajmy nową zmienną globalną private BindingSource
bindingSource2 = new BindingSource(), a do ciała naszej metody DataGridFill wpiszmy
ten kod:
/// sciezka do naszej bazy
string path = openFileDialog1.FileName.ToString();
/// polecenie polaczenia jakie wyslemy do Serwera
string connectionString = "Data
Source=.\\SQLEXPRESS;AttachDbFilename=" +
path + ";Integrated Security=True;User Instance=True";
/// komenda select ktora wykona baza
string commandString = textBox1.Text;
string commandDetail = "Select Opis_Zadania as 'Opis
zadania',ID_Pracownika as 'ID' from Zadanie";
/// nazwa tabeli ktora wyswietlimy
try
{
SqlConnection connection = new SqlConnection(connectionString);
/// Nowy adapter potrzebny do wypelnienia drugiego
/// dataGrida
SqlDataAdapter DataAdapterDetail = new
SqlDataAdapter(commandDetail, connection);
/// SqlDataAdapter wyciaga z bazy na ktora "wskazuje" polaczenie
//rekordy ktore zwraca sa wynikiem commandString
DataAdapter = new SqlDataAdapter(commandString , connection);
/// Dodajemy do DataSet.Tables tabele o nazwie tableName
DataAdapter.Fill(dataSet1,"show");
// wpisanie drugiej tabeli do dataseta
DataAdapterDetail.Fill(dataSet1, "detail");
// tworzymy realcje która zrobi za nas cała robote i bedzie
zmieniać
// dane w dataGridView2
DataRelation Relation = new DataRelation("FK_Zadanie_Pracownik",
dataSet1.Tables["show"].Columns["ID"],
dataSet1.Tables["detail"].Columns["ID"]);
// dodajemy relacje
dataSet1.Relations.Add(Relation);
/// zamykamy polaczeniem z baza
connection.Close();
/// jako zrodlo danych (DataSource) naszego DataGridView podajemy
// całego dataseta
bindingSource1.DataSource = dataSet1;
// i nazwa tabeli by nasz DGV wiedzial z ktorej tabeli ma
// czerpac dane
bindingSource1.DataMember = "show";
// drugi bindingSource ma zródło jako pierwszy bindingsource
bindingSource2.DataSource = bindingSource1;
//ale odwołuje się do stworzonej przez nas realacji, a nie do
tabeli
bindingSource2.DataMember = "FK_Zadanie_Pracownik";
// podczempiamy odpowiednio zródła do DGV i ukrywamy kolumny
dataGridView1.DataSource = bindingSource1;
dataGridView1.Columns["ID"].Visible = false;
dataGridView2.DataSource = bindingSource2;
dataGridView2.Columns["ID"].Visible = false;
}
catch (Exception ex)
{
/// Jesli cos pojdzie nie tak np. zla nazwa tabeli, zla sciezka do
bazy
/// wyswitli nam sie MessageBox z bledem
MessageBox.Show("Wyjatek : " + ex.Message, "BŁAD");
}
Gotowe! Teraz nie grozi nam już mozolne włączanie i wyłączanie programu, gdy popełnimy błąd 
Po skompilowaniu i uruchomieniu koocowy efekt powinien byd podobny do następującego:

Podobne dokumenty