Visual Studio Express 2013 kaskadowe listy rozwijalne

Tworzenie kaskadowych list rozwijalnych (Visual Studio 2013 for Web)

1. Ponieważ nasze listy rozwijalne będą pobierały dane z bazy danych, na początku należy utworzyć odpowiednią strukturę w bazie danych, która będzie odpowiedała naszym potrzebom. Do naszego przykładu stworzyłem następujący zestaw tabel. Stworzyłem 3 tabele: pierwsza będzie przechowywała dane dotyczące kontynentów, druga dane dotyczące krajów i trzecia dane dotyczące miast. Na początku będziemy wybierali kontynent, później kraj, ale już w zależności co wybraliśmy w kroku 1 czyli przy wyborze kontynentu a na końcu miasto, ale w zależności od naszego wyboru w kroku 2 czyli przy wyborze kraju. Struktura bazy poniżej

CONTINENTS (tabela 1 która będzie zawierała nazwy kontynentów i ich identyfikatory)
ID int
ContinentName varchar(50)

COUNTRIES (tabela 1 która będzie zawierała dane dotyczące krajów)
ID int
CountryName varchar(50)
ContinentID int

CITIES (tabela 3 która będzie zawierała dane dotyczące miast)
ID int
CityName varchar(50)
CountryID int

2. W bazie danych należy utworzyć odpowiednie procedury, które będą zasilały danymi odpowiednie listy

procedura do zasilania danymi listę „Kontynenty”
Create procedure spGetContinents
as
Begin
Select ID, ContinentName from Continents
End

Procedura do zasilania danymi listę „Kraje” (zwóć uwagę, że pojawia się tutaj zmianna, która spełnia funkcję parametru. Jako parametr będzie podawane ID kontynentu który wybraliśmy z listy „Kontynenty”)

Create procedure spGetCountryByContinentID
@ContinentID int
as
Begin
Select ID, CountryName from Countries
where ContinentID=@ContinentID
End

Procedura do zasilania danymi listę „Miasta” (zwóć uwagę, że pojawia się tutaj zmianna, która spełnia funkcję parametru. Jako parametr będzie podawane ID kraju który wybraliśmy z listy „Kraje”)

Create procedure spGetCitiesByCountryID
@CountryID int
as
Begin
Select ID, CityName from Cities
where CountryID=@CountryID
End

Aby stworzyć procedurę w bazie należy zazlaczyć całą procedurę i uruchomić polecenie Execute (w VS także kombinacją klawiszy CTRL + SHIFT + E)

Aby sprawdzić i uruchomić procedurę wystarczy na końcu nazwy dopisać wartość parametru, zaznaczyć całą nazwę procedury (ale tylko samą nazwę bez wyrażenia create procedure) wraz z wpisaną wartością parametru i uruchomić procedurę (Ctrl+Shift+E)

3. Przechodzimy do kodu naszego formularza i dodajemy na początku kilka bibliotek

using System.Data;
using System.Data.SqlClient;
using System.Configuration;

4. Następnie wewnątrz sekcji public partial class _Default : Page dodajemy procedurę o nazwie GetData, która będzie zwracałą nazwę procedury do użycia (chodzi o nazwy procedur stworzonych w kroku 2)
private DataSet GetData(string SPName, SqlParameter SPParameter)
{

}
parametry procedury:
string SPName – Stored Procedure Name czyli zwróci odpowiednią nazwę procedury którą stworzylismy wcześniej w kroku 2.
SqlParameter SPParemater – Stored Procedure Parameter, chodzi o wartość parametry przy procedurach „GetCountryByContinentID” oraz „GetCityByCountryID”

Cała procedura poniżej
private DataSet GetData(string SPName, SqlParameter SPParameter)
{
string CS = ConfigurationManager.ConnectionStrings[„DefaultConnection”].ConnectionString;
SqlConnection con = new SqlConnection(CS);
SqlDataAdapter da = new SqlDataAdapter(SPName, con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
if(SPParameter != null)
{
da.SelectCommand.Parameters.Add(SPParameter);
}
DataSet DS = new DataSet();
da.Fill(DS);
return DS;
}

5. Następnie dopisujemy polecenia do procedury LoadPage
if (!IsPostBack)
{
ddlContinents.DataSource = GetData(„spGetContinents”, null);
//przyczepiamy wynik procedury spGetContinents do ddlContinents

ddlContinents.DataBind();
//
}

6. W kolejnym kroku przechodzimy do widoku projektu, następnie do źródła strony przy deklaracji kontrolki DropDownList w naszym przypadku ddlContinents dodajemy dwie właściwości
DataTextField=”ContinentName” – która mówi, że mają się wyświetlać nazwy kontynentów
DataValueField=”ID” – która mówi, że ukrytymi wartościami pola mają być identyfikatory kontynentów.

7. Aby w pierwszym „wierszu” listy kontynenty wpisać tekst „Wybierz kontynent” należy uzupełnić sekcję if (!IsPostBack) w procedurze LoadPage o następujące wpisy

ListItem liContinents = new ListItem(„Wybierz Kontynent”, „-1″);
ddlContinents.Items.Insert(0,liContinents);

W pierszej linii tworzymy listę liContinents do której dodajemy jeden wpis „Wybierz Kontynent” a następnie w drugiej linii dodajemy ta listę do listy w kontrolce ddlContinents.

Takie same listy tworzymy do kontrolek ddlCountries oraz ddlCities.

8. Teraz zrobimy coś takiego. W momencie kiedy jeszcze nic nie wybraliśmy, listy „Kraje” i „Miasta” powinny być wyłączone/nie aktywne. W tym celu w sekcji if(!IsPostBack) dopisujemy dwa wiersze.

ddlCountries.Enabled = false;
ddlCities.Enabled = false;

9. teraz musimy oprogramować co się stanie w momencie zmiany wartości w kontrolce ddlContinents czyli w momencie kiedy wybierzemy jakiś kontynent. Wynik tego działania to włączenie/aktywowanie listy „Krajów” w zależności od wybranego Kontynentu.

W tym celu przchodzimy do widoku projektu/formularza i dwukrotnie klikamy na naszą kontrolkę ddlContinents. Efektem naszego działania jest przejście do kodu naszej strony i automatyczne stworzenie procedury o nazwie.

protected void ddlContinents_SelectedIndexChanged(object sender, EventArgs e)

następnie wypełniamy tą procedurę treścią

protected void ddlContinents_SelectedIndexChanged(object sender, EventArgs e)
{
if(ddlContinents.SelectedIndex == 0)
{
//jeśli wybranym elementem jest 0 to brak reakcji
// pamiętajmy, że element 0 to napis „Wybierz Kontynent”, czyli tak naprawdę nie zostła wybrana żadna wartość/żaden kontynent
}
else
{
// jeśli wybraliśmy jakiś kontynent to
ddlCountries.Enabled = true; // włączamy listę ddlCountries
SqlParameter parameter = new SqlParameter(„@ContinentID”,ddlContinents.SelectedValue);
// tworzymy nową zmienna gdzie wpisujemy do nie wartość ID wybranego kontynentu

DataSet DS = GetData(„spGetCountryByContinentID”, parameter);
ddlCountries.DataSource = DS;
ddlCountries.DataBind();
}
}

Następnie musimy dodać dwie właściwości, w kodzie, do kontrolki ddlCountries
DataTextField=”CountryName” – która mówi, że mają się wyświetlać nazwy krajów
DataValueField=”ID” – która mówi, że ukrytymi wartościami pola/kontrolki mają być identyfikatory krajów.

Jednakże czeka nas jeszcze jedna niespodzianka. W momencie zmiany wartości w kontrolce ddlContinents czyli w momencie wyboru jakiegoś kontynentu znika nam pierwszy wiersz „Wybierz Kraj” z kontrolki ddlCountries. Aby temu zapobiec trzeba skopiować część kodu z sekcji PageLoad do sekcji protected void ddlContinents_SelectedIndexChanged(object sender, EventArgs e) czyli tam gdzie oprogramowujemy zachowanie się aplikacji po wyborze kontynentu.
Część kodu do skopiowania:
ListItem liCountries = new ListItem(„Wybierz Kraj”, „-1″);
ddlCountries.Items.Insert(0, liCountries);

10. Kolejny krok to oprogramować zmianę wartości w kontrolce ddlCoutries czyli moment wyboru kraju. Wynikiem powinno być włączenie/aktywacja kontrolki ddlCities oraz wypełnienie tej kontrolki danymi wg wyboru w kontrolce ddlCoutries.
W tym celu w widoku projektu klikamy dwukrotnie na kontrolkę ddlCountries i automatycznie przechodzimy do kodu gdzie tworzy nam się automatycznie procedura o nazwie ddlCountries_SelectedIndexChange. My już oprogramowywaliśmy w taki sposób kontrolkę ddlContinents, wystarczy więc kopiować zawartość procedury ddlContinents_SelectedIndexChange i wkleić ją do ddlCountries_SelectedIndexChange odpowiednio modyfikując zawartość. Gotowa procedura poniżej. Wyjaśnienie procedury ddlContinents_SelectIndexChange w kroku 9.

protected void ddlCountries_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlCountries.SelectedIndex == 0)
{
//jeśli wybranym elementem jest 0 to brak reakcji
// pamiętajmy, że element 0 to napis „Wybierz Kraj”, czyli tak naprawdę nie zostła wybrana żadna wartość/żaden kraj
}
else
{
// jeśli wybraliśmy jakiś kraj to
ddlCities.Enabled = true; // włączamy listę ddlCities
SqlParameter parameter = new SqlParameter(„@CountryID”, ddlCountries.SelectedValue);
// tworzymy nową zmienna gdzie wpisujemy do nie wartość ID wybranego kraju

DataSet DS = GetData(„spGetCitiesByCountryID”, parameter);
ddlCities.DataSource = DS;
ddlCities.DataBind();
ListItem liCities = new ListItem(„Wybierz Miasto”, „-1″);
ddlCities.Items.Insert(0, liCities);
}
}

11. Zwóćmy teraz uwagę na fakt, że przy zmianie wartości w liście Kontynentów wartość w liście Krajów zmienia sie na „Wybierz Kraj” a wartość w liście Miasta zostaje nie zmienna. Takiej sytuacji nie chcemy. Oczekiwane zachowanie aplikacji jest takie, że przy zmianie wartości listy Kontynenty wartość listy Kraje wskazuje na wartość „Wybierz Kraj” ale wartość na liście Miasta także przeskakuję na „Wybierz Miasto” i dodatkowo staje się wyłączona. Jak to zrobić?

Musimy przejść do kodu strony i dopisać odpowiedni kod do procedury ddlContinents_SelectIndexChange, ponieważ tam oprogramowaliśmy zachowanie aplikacji przy zmianie wartości listy Kontynenty, czyli przy wyborze nowego Kontynentu.

Następnie dodajemy do tej procedury następujące wpisy:
ddlCities.SelectedIndex = 0; // zmiana wartości w liście „ddlCities” na „Wybierz Miasto”
ddlCities.Enabled = false; // wyłączenie (wyrzarzenie) listy „ddlCities”

12. Koleny przypadek którym należy się zająć to sytuacja kiedy z listy Kontynenty wybierzemy wartość „Wybierz Kontynent”. Wtedy wartość na liście Kraje powinna zmienić się na „Wybierz Kraj”, jeśli była inna i cała lista Kraje powinna był wyłączona/wyszarzona. W tym celu przechodzimy do procedury dllContinents_SelectIndexChange do sekcji if(ddlContinents.SelectedIndex == 0) i dopisujemy kod:

ddlCountries.SelectedIndex = 0; // zmiana wartości w liście „ddlCountries” na „Wybierz Kraj”
ddlCountries.Enabled = false; //wyłączenie/wyszarzenie listy „ddlCountries”

w tym samym momencie aplikacja powinna się zachować odkładnie tak samo w odniesieniu do listy Miast. W tym celu należy dodatkowo dodać powyższy kod z lekką modyfikacją:

ddlCities.SelectedIndex = 0; // zmiana wartości w liście „ddlCities” na „Wybierz Miasto”
ddlCities.Enabled = false; //wyłączenie/wyszarzenie listy „ddlCities”

13. Analogincznie do punktu 12 trzeba oprogramować sytuację kiedy wybieramy opcję „Wybierz Kraj” na liście Kraje, kiedy mamy już wybraną wartość na liście Miasta. W tym celu przechodzimy do procedury dllCountries_SelectIndexChange do sekcji if(ddlCountries.SelectedIndex == 0) i dopisujemy kod:

ddlCities.SelectedIndex = 0; // zmiana wartości w liście „ddlCities” na „Wybierz Miasto”
ddlCities.Enabled = false; //wyłączenie/wyszarzenie listy „ddlCities”

Teraz w momencie, kiedy mamy wybrane miasto, zmieniamy wybór na liście Kraje na „Wybierz Kraj” lista Miasta przyjmuje wartość „Wybierz Miasto” i zostaje wyszarzona/wyłączona.

Koniec :)