Avatar billede radiv Nybegynder
21. oktober 2004 - 13:19 Der er 9 kommentarer og
1 løsning

Flere dropdownlister, der henter indhold fra databaser

Jeg vil lave nogle dropdownlister, der henter sine værdier og tekster fra nogle tabeller i min database.

Når man vælger noget i liste 1, bliver liste 2 udfyldt med de alternativer som det valgte element giver. Dette skal så kunne gentages.

Findes der en god tutorial på dette, eller har I et forslag til hvordan det kan løses uden for meget redundans i databasen?
Avatar billede radiv Nybegynder
22. oktober 2004 - 11:07 #1
Er det fordi spørgsmålet er ringe formuleret jeg ikke får nogle svar?

Så vil jeg forklare igen:

Jeg vil have en dropdownliste, der henter værdier fra en tabel i en database (ved hjælp af et typed dataset). Det har jeg styr på.

Næste punkt er at den værdi jeg vælger, skal aktivere dropdownliste 2 med aktuelle værdier fra en anden tabel i samme database (og samme dataset).

Altså:
DropDownList1: Kategori1
              Kategori2
              Kategori3

<vælger kategori1 i DropDownList1>

Dropdownlist2: Subkategori1_1
              Subkategori1_2
              Subkategori1_3

ELLER

<vælger kategori2 i DropDownList1>

Dropdownlist2: Subkategori2_1
              Subkategori2_2
              Subkategori2_3

...osv


Håber det er mere forståeligt.

Den anden del af spørgsmålet er hvordan jeg nemmest designer tabellene i databasen.Der skal gerne være muligt at gentage mønsteret et vilkårlig antal gange.
Avatar billede snepnet Nybegynder
25. oktober 2004 - 08:03 #2
nøh.... det var egentlig formuleret ganske fint - vi sover nok bare :o)

hvis det stadig er aktuelt :
har du de afhængige tabeller du skal bruge til dropdownlisterne i ét dataset, og ligger relationerne i det ?

mvh
Avatar billede radiv Nybegynder
25. oktober 2004 - 12:01 #3
Jeg har ikke fastlagt strukturen endnu, og det er måske et separat spørgsmål i en anden kategori?

Alle valg (kategorier) skal registreres i en anden tabel, så alle relationer vil ligge i datasetet.

Men hvis vi antager at alt ligger i et dataset, har du så et bud på hvordan det kan gøres?

Jeg vil lige kigge om jeg kan finde noget der kan bruges til databasen i de øvrige kategorier.
Avatar billede snepnet Nybegynder
25. oktober 2004 - 21:35 #4
hej radiv :o)

tjoh... der er jo lidt forskellige måder at gribe det an på.... jeg tror egentlig jeg ville koble dem ret hårdt sammen - og betragte det som én søgekontrol.

hvis vi siger du har et dataset (ds) med 3 tabeller T1, T2 og T3 med relationerne RT1_T2, og RT2_T3, kunne et skelet se ud lidt i denne stil :
og... dropdownlisterne dd1, dd2 og dd3
(det er sådan lidt pseudoagtigt, og uden fejlcheck og fuldstændig ugenerisk - lige som i lige ud af landevejen :o).

desuden vil jeg tro det vil blive det letteste, rent perfomancemæssigt hurtigste, hvis du klasker datasætte i session - så du får lige denne :

protected DataSet ds
{
  get
  {
    return (object)Session["listdata"] != null ? (DataSet)Session["listdata"] : null;}
  }
  set
  {
    Session["listdata"] = value;
  }
}

// ved load henter du data, og fylder den første dropdown:
ds = someDal.GetListData();
dd1.DataSource = ds.Tables["T1"];
// her sætter teksten til hvad den nu skal være, og value til nøglen du bruger i -relationen
// altså
dd1.DataTextField = ...
dd1.DataValueField = ...

// og du vil så have nogle handlere til når der vælges i listerne:

void dd1_SelectedIndexChanged(...)
{
  // du høster lige det row det drejer sig om
  int key = int.Parse(((DropDownList)sender).SelectedValue);
  DataRow dr = ds.Tables["T1].Rows.Find(key)[0];
  dd2.DataSource = dr.GetChildRows("RT1_T2");
  // her sætter du værdierne på samme måde som med som med dd1
  dd2.DataBind();
}

void dd2_SelectedIndexChanged(...)
{
  int key = int.Parse(((DropDownList)sender).SelectedValue);
  DataRow dr = ds.Tables["T2].Rows.Find(key)[0];
  dd3.DataSource = dr.GetChildRows("RT2_T3");
  dd3.DataBind();
}

void dd3_SelectedIndexChanged(...)
{
  // der skal så nok ske noget helt andet her
}

var det nok til at komme igang på ?
(ellers må du sige til)

mvh - og undskyld jeg ikke har svaret før.
Avatar billede radiv Nybegynder
26. oktober 2004 - 22:29 #5
Tak snepnet, det ser fornuftigt ud. Jeg vender tilbage torsdag når jeg har fået prøvet det ud.
Avatar billede snepnet Nybegynder
26. oktober 2004 - 22:54 #6
det er bare iorden - vi skrives ved :o)
mvh
Avatar billede radiv Nybegynder
29. oktober 2004 - 16:39 #7
Så er jeg her!

Jeg sidder fast ved
dd2.DataSource = dr.GetChildRows("RT1_T2");

Hvordan navngiver jeg relationen?

Jeg har tre tabeller i datasettet, alle har en primary key, tabel 2 har en foreign key i tabel 1's primary key osv.

Jeg er bare ikke helt med på hvordan "key", altså det element jeg vælger i dd1, skal udvælge de riktige poster fra tabel2.
Avatar billede snepnet Nybegynder
29. oktober 2004 - 18:10 #8
hej radiv :o)

du kan lige få et eksempel jeg smed i et andet spørgs.... hvor det hele bygges op i koden (altså både tabeller og selve datasættet).

    public class SomeDataSet : DataSet
    {
        public SomeDataSet()
        {
            this.Tables.Add(new T1());
            this.Tables.Add(new T2());

            this.Relations.Add("RelationT1_T2", this.Tables[0].Columns["id"], this.Tables[1].Columns["id"]);
        }
    }

    public class T1 : DataTable
    {
        public T1() : base("T1")
        {
            DataColumn dc = this.Columns.Add("Id", typeof(int));
            dc.AllowDBNull = false;
            dc.AutoIncrement = true;
            dc.AutoIncrementSeed = 0;
            dc.AutoIncrementStep = 1;

            DataColumn[] pKeys = {c};
            this.PrimaryKey = pKeys;

            dc = this.Columns.Add("T1_String",typeof(string));
            dc.DefaultValue = "T1";
        }
    }

    public class T2 : DataTable
    {
        public T2() : base("T2")
        {
            DataColumn dc = this.Columns.Add("id", typeof(int));
            dc.AllowDBNull = false;
            dc.AutoIncrement = true;
            dc.AutoIncrementSeed = 0;
            dc.AutoIncrementStep = 1;

            DataColumn[] pKeys = {c};
            this.PrimaryKey = pKeys;

            dc = this.Columns.Add("T2_String",typeof(string));
            dc.DefaultValue = "T2";
        }
    }

man skal ikke nødvendigvis lave det hele, man kan uden problemer tage et eksisterende dataset som bare er genereret udfra et "sug" i databasen, og proppe relationerne ind på det ved :

someDataSet.Relations.Add(...);
og tilsvarende kan du på en eksisterende tabel sætte en nøgle ved :
someDataSet.Tables[0].PrimaryKey = new DataColumn[] {someDataSet.Tables[0].Cloumns["Id"];

på ovenstående vil du så du lave noget som dette :

SomeDataSet ds = new someDatalayer().GetSomething();

foreach(DataRow dr in ds.Tables["T1"].Rows)
{
  DataRow childRows = dr.GetChildRows("RelationT1_T2");
}

Så hvis du har fat i en specifik række i tabel 1 - og id'et fra denne, skulle du kunne få dine childrows på relationen :

DataRow[] dr = someRow.GetChildRows("RelationT1_T2");

Det kan være vældig praktisk, hvis du definerer nogle konstanter på dine klasser så du undgår indexering ved "RelationT1_T2"... Prøv at se denne :

    public class SomeDataSet : DataSet
    {
        public const string RelationT1_T2 = "RelationT1_T2";

        public SomeDataSet()
        {
            this.Tables.Add(new T1());
            this.Tables.Add(new T2());
            this.Relations.Add(RelationT1_T2, this.Tables[0].Columns["id"], this.Tables[1].Columns["id"]);


.
.
.

Det ville give muligheden for :

DataRow[] dr = someRow.GetChildRows(SomeDataSet.RelationT1_T2);

Samme trick kunne du lave med tabel- og kolonnenavne.

Så har du kun din egentlig navngivning stående ét sted med "" - og du henter den så der hver gang der er behov for det.

Var det skudt forbi - eller kan du bruge det til noget ?

mvh
Avatar billede radiv Nybegynder
04. november 2004 - 11:50 #9
Det var en stor mundfuld, men det gav god inspiration.

Jeg har dog valgt en anden løsning, som jeg kort viser her:

Jeg har tre tabeller, der den første (kategori) indeholder kategoriID og kategoriNavn, den anden (subKategori) indeholder subKategoriID, subKategoriNavn og kategoriNummer, og den tredje (producent) indeholder producentID, producentNavn og subKategoriNummer.

Når siden loader, er kun den første dropdown enabled.

private void droptest_PreRender(object sender, System.EventArgs e)
        {
           
            if (!IsPostBack)
            {

                //laver nye dataview der arbejder på kategori
                DataView dvKategori = new DataView(Data.kategori);
                                                               
                //populer dropdownlist kategori
                ddlEn.DataSource = dvKategori;
                ddlEn.DataTextField = "kategoriNavn";
                ddlEn.DataValueField = "kategoriID";
                ddlEn.DataBind();
                ddlEn.Items.Insert(0, new ListItem("----Vælg kategori", "-1"));

            }

        }

        private void ddlEn_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            // find den valgte kategori
            int kategori = int.Parse(((DropDownList)sender).SelectedValue);

            DataView dvSubKategori = new DataView(Data.subKategori);
                           
            dvSubKategori.RowFilter = "kategoriNummer = " + kategori;
            ddlTo.DataSource = dvSubKategori;
            ddlTo.DataTextField = "subKategoriNavn";
            ddlTo.DataValueField = "subKategoriID";
            ddlTo.DataBind();
            ddlTo.Items.Insert(0, new ListItem("----Vælg subkategori", "-1"));
            ddlTo.Enabled = true;
        }

Det samme gentages så for dropdownlisten til producent.

Måske lidt "quick and dirty", men det fungerer.
Avatar billede snepnet Nybegynder
05. november 2004 - 08:29 #10
hej radiv :o)

jeg synes det er helt fint.... det er jo sådan set også samme model - og forskellen ligger bare i hvor meget du lægger i dit dataset.
datasættet kan gå fra det helt generiske (hvis du f.eks. fylder et new DataSet() op med en adapter) - og til typestærke datasets med masser af specielle metoder og properties.
den jeg skrev (altså den med datasættene) lander et sted midt imellem :o)

hvis listerne er nogle du skal bruge på andre sider - kunne du overveje at lægge dem i en selvstændig kontrol istedet....

mvh
(jeg lægger et svar hvis du vil af med noget :o)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester