
A mellékelt példa üzembeállításához a következő lépések szükségesek: hozzon létre egy virtuális könyvtárat VoteProject névvel, mely mutasson a mellékelt példa könyvtárára. Ehhez válassza az Intézőben a mappán jobb gombbal történ kattintás után a Tulajdonságok menüpontot, majd a Webmegosztás lapon végezze le ezt a műveletet.
Ezt követően a mellékelt Vote.sql állományt futassa le MS SQL szerver SQL Query Analyzer programjával, hogy a szükséges adatbázis a szükséges tartalommal létrejöjjön.
Végül a VoteControl.ascx.cs forráskód 57. sorában lévő connStr változó értékét módosítsa úgy, hogy a Vote adatbázis elérhető legyen.
Az adatbázis
A létrehozott Vote nevű adatbázisba két táblát helyeztünk el. Az egyik Question névvel a kérdéseket tárolja, melyből mindig egy-egy kerül feltevésre. A másik Answer nevű táblába a lehetséges válaszok kerültek. Mivel egy kérdés több válasz is tartozhat ezért a QuestionID oszlop alapján kötöttük össze a két táblát. Az Answer táblába a válasz szövegén kívül még bekerül egy olyan oszlop, melyben számlálhatjuk, hogy az adott kérdésre hány válasz érkezett eddig.
Szavazás
Készítsük most el a web kontrolt, melyen úgy kell működnie, hogy két különböző képet is mutathasson attól függően, hogy szavazni kell, vagy épp az eredményt megjeleníteni.
Az új kontrol létrehozásához válasszuk a Project - Add Web User Control menüpontot. VoteControl.ascx néven hozzuk létre az új kontrol forrását. A kontrolt úgy tudjuk a web lapunkra a legegyszerűbben tenni, hogy a Solution Explorer-ből Drag and Drop-al megfogjuk és a kívánt helyre húzzuk.
A kontrolon belül két függvényt fogunk létrehozni: az egyik lesz a ShowQuestion, melynek hatására a kérdés jelenik meg szavazási lehetőséggel. A másik esetben a ShowAnswer függvényben az eredmény megjelenítését fogjuk megvalósítani.
A kontrol területére felteszünk egy RadioButtonList kontrolt, mely arra kell, hogy a lehetséges válaszokat megjelenítsük és a felhasználó ezek közül válasszon. A RadioButtonList kontrol biztosítani fogja, hogy egy kérdésre, csak egyféle válasz adható. Elhelyezünk egy DataGrid kontrolt is szintén itt, melyre majd az eredmény lista megjelenítésénél lesz szükségünk. Mivel e két kontrol közül mindig csak az egyikre van szükségünk, attól függően, hogy épp kérdezünk, vagy az eredményt mutatjuk, így ezeknél a Visible property-vel változtatjuk majd a láthatóságukat.
A kontrol szélességét fix méretre, pontosan 200 pixelre állítjuk. Így web oldalunk tervezésekor ezt figyelembe tudjuk venni. A kontrol magassága viszont változó lehet, annak függvényében, hogy egy kérdésre hány lehetséges válasz van. Mivel a kontrol úgy lett megtervezve, hogy a válaszok száma tetszőleges lehet, így a magassága automatikusan kell, hogy változzon. A szavazatott elküldő gomb minden esetben a kontrol jobb alsó sarkába kerül a válaszok számától függetlenül.
Nézzük mit miként is működik a ShowQuestion függvény.
Első lépésként összeállítunk egy lekérdezést, melyben a függvényünk paramétereként megadott azonosítóval rendelkező kérdést és az arra adható válaszokat tudakoljuk meg az adatbázisunktól.
public void ShowQuestion(int questionID)
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT Question.QuestionText, Answer.AnswerID, Answer.AnswerText ");
sb.Append("FROM Question INNER JOIN Answer ON Question.QuestionID = Answer.QuestionID ");
sb.Append("WHERE (Question.QuestionID = " + questionID.ToString() + ")");
Ezt követően futtatjuk a lekérdezést, melynek eredményét egy DataSet-ben tároljuk.
...
SqlDataAdapter da = new SqlDataAdapter(sb.ToString(), connection);
DataSet ds = new DataSet();
da.Fill(ds);
...
Ha a lekérdezés hozott eredményt, akkor beállítjuk a Label1-et, melyen a kérdés jelenik meg.
if (ds.Tables[0].Rows.Count>0)
{
Label1.Text = ds.Tables[0].Rows[0]["QuestionText"].ToString();
Ezt követően egy ciklussal feltöltjük a RadioButtonList elemeit annyi tétellel ahány adható válasz van. A válaszok szövege mellé eltároljuk az adott válasz egyedi azonosítóját is, hogy a későbbiekben könnyebb dolgunk legyen amikor egy szavazást fel kell dolgoznunk.
DataRowCollection drc = ds.Tables[0].Rows;
for (int i=0; i<drc.Count; i++)
{
li = new ListItem(drc[i]["AnswerText"].ToString(), drc[i]["AnswerID"].ToString());
RadioButtonList1.Items.Add(li);
}
...
Eredmény
Amikor a felhasználó a kérdés oldalon a gombra kattint, akkor jön létre a szavazás eseménye. Ebben az esetben növeljük eggyel az adott válaszhoz tartozó számlálót, majd automatikusan megjelenítjük az eredményt.
A növeléshez létrehoztunk egy IncrementAnswer nevű függvényt, mely paraméterként az Answer tábla egyedi azonosítóját várja, amelyik sornál a növelést el kell végezni. Ezt megtudjuk a RadioButtonList kiválasztott eleméből, mivel ott minden kérdésnek tároltuk az azonosítóját is. A függvényünk egy számot ad vissza, mely a válaszhoz tartozó kérdés egyedi azonosítója lesz. Ez az egyedi azonosító szükséges ahhoz, hogy a ShowAnswer függvényt meghívhassuk, mely csak úgy tudja megjeleníteni az eredményt, hogy paraméterként meg kapja azt, hogy melyik kérdésre adott válaszokat is kell előkeresni.
Az IncrementAnswer nevű függvényünk egy tárolt eljárást hív meg, amely elvégzi a szükséges sor számlálójának növelését, majd visszaadja a sorhoz tartozó kérdés azonosító számot.
private void Button1_Click(object sender, System.EventArgs e)
{
ShowAnswer(IncrementAnswer(Convert.ToInt32(RadioButtonList1.SelectedItem.Value)));
}
A ShowAnswer úgy jeleníti meg az eredményt, hogy futtat egy lekérdezést paraméterként kapott kérdés azonosítóval.
public void ShowAnswer(int questionID)
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT Question.QuestionText, Answer.AnswerText, Answer.AnswerCount ");
sb.Append("FROM Question INNER JOIN Answer ON Question.QuestionID = Answer.QuestionID ");
sb.Append("WHERE (Question.QuestionID = " + questionID.ToString() + ")");
A lekérdezés eredménye ismét egy DataSet-be kerül.
SqlDataAdapter da = new SqlDataAdapter(sb.ToString(), connection);
DataSet ds = new DataSet();
da.Fill(ds);
Ha a lekérdezésnek volt eredménye, akkor ismét megjelenítjük a kérdést a Label1 kontrolon, majd az eredmény halmazt a DataGrid-hez kötjük, melynél már beállítottuk, hogy csak a válaszok szövege és a válaszokra adott szavazatok száma jelenjen meg két oszlopban.
if (ds.Tables[0].Rows.Count>0)
{
Label1.Text = ds.Tables[0].Rows[0]["QuestionText"].ToString();
DataGrid1.DataSource = ds.Tables[0].DefaultView;
DataGrid1.DataBind();
}
...
A kontrol felhasználása
Mivel a kontrolt programból is el kell érnünk ezért tegyük meg a WebForm1.aspx.cs forráskódban a következő kiegészítést:
protected VoteControl VoteControl1;
Erre azért van szükségünk, mert ugyan a kontrolt már elhelyeztük a web oldalon, de a forráskódbeli deklarációja nem jön létre automatikusan, így ha szükségünk van ennek forráskódból történő elérésére, akkor nekünk kell megtenni a megfelelő hivatkozást.
Ezek után már használtjuk programból.
A szavazógép működtetéséhez a ShowQuestion függvényt kell csak meghívnunk, paraméterként átadva számára annak a kérdésnek az azonosítóját, melyet megszeretnénk szavaztatni.
private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
VoteControl1.ShowQuestion(Convert.ToInt32(ListBox1.SelectedItem.Value));
}
Szükség esetén a ShowAnswer függvény is meghívható direktbe, így lehetőségünk van szavazás nélkül is az eredmény megjelenítésére. Erre valós helyzetben szükségünk is van, hiszen ha már olyan felhasználó jár az oldalunkon, aki már szavazott, akkor azt nem szeretnénk, hogy újra szavazzon, ilyenkor célszerű rögtön az eredményt mutatni az ő számára.
Annak eldöntésére, hogy ki szavazott és ki nem célszerű cookie-t használni.