Avatar billede fileto Seniormester
10. juli 2004 - 14:07 Der er 11 kommentarer og
1 løsning

Problemer med med panels

Hej

Jeg er ved at lave en form med en antal checkboxe og en panel for hver checkbox.
Når man "hakker" en checkbox af så skal panelen dukke op med dets controller.

Jeg gør dette ved at putte checkboxe og panels ned i en placeholder, panels er lagt ind i
et array så man kan tilgå dem med et index.

Samtidig har jeg en eventhandler der putter controller i panels.

Første gang jeg putter in control i en panel ser alt fint ud. Controllen viser sig på sin plads.

Men når jeg putter noget i den næste panel så forsvinder indholdet i den første panel.


Min kode ser således ud :

#code start
CheckBox chkFeature = new CheckBox();
Panel[] lstFeature = new Panel[5];
for (features=1;features<numberOfSelectedFeatures+1;features++)
{
    chkFeature = new CheckBox();
    chkFeature.Text = featureName[features-1];
    chkFeature.AutoPostBack = true;
    chkFeature.ID = "" + (features) + "";
    chkFeature.CheckedChanged += new EventHandler(FeaturePannel);
    plhSearchHolder.Controls.Add(chkFeature);
    lstFeature[features-1] = new Panel();
    plhSearchHolder.Controls.Add(lstFeature[features-1]);
}
private void FeaturePannel(object sender, System.EventArgs e)
{
    CheckBox chkFeat = new CheckBox();
    chkFeat = (CheckBox)sender;
    string fId = chkFeat.ID;
    int featix = Int32.Parse(fId);
    if (chkFeat.Checked)
    {
        rating.Text = "test";
        lstFeature[featix-1].Controls.Add(rating);
    }
    else
    {
        lstFeature[featix-1].Controls.Remove(rating);
    }
    lstFeature[featix-1].Style.Add("top", "" + (baseTop+(space*(featix-1))) + "px");
    lstFeature[featix-1].Style.Add("left", "" + featuredetailCol + "px");
    lstFeature[featix-1].Style.Add("position", "absolute");
    lstFeature[featix-1].EnableViewState = true;
    lstFeature[featix-1].DataBind();

}
#code slut

Hvorfor forsvinder inholdet i et array element når jeg putter noget i en andet arrayelement?
Bruger jeg panels forkert? eller hvad gør jeg galt?
Avatar billede snepnet Nybegynder
10. juli 2004 - 18:00 #1
Hej igen fileto :o)
Det bliver en lidt længere forklaring... Jeg poster noget til dig senere i aften.
(det bliver nok ikke før ved en 22-23 tiden).
Mvh
Avatar billede fileto Seniormester
10. juli 2004 - 19:43 #2
super :-)
Avatar billede snepnet Nybegynder
10. juli 2004 - 23:03 #3
Nå - jeg nåede det næsten :o) (håber du stadig er oppe)

Nu har jeg ikke set hele din kode, men jeg gætter på at de første linier du har skrevet er noget der kører i page_load eller tilsvarende.

Det ser ud til at du opbygger siden på samme måde hver gang... Du starter altså med en "nulstillet" side efter hvert postback.

Hvis der er klikket på en checkbox, vil du efter opbygningen få kørt din handler - som så sætter rating ind. Du vil derfor aldrig kunne få vist andet end den "nulstillede" side + det der er sket i handleren.

(Jeg er for øvrigt meget interesseret i at se hvordan du initialiserer det rating-objekt du indsætter i handleren.)

Du kan gøre det, at du selv sørger for at gemme oplysninger om hvad der skal vises, mellem roundtrips, men du kan også opbygge tingene på en måde så du i højere grad "får det foræret".

Der er temmelig mange måder du sådan rent teknisk kunne få det til at virke, men du kan lige se én her.

// bare en konstant til eksemplet...
private const int ITEMS = 10;

// page_load
private void Page_Load(object sender, System.EventArgs e)
{
    CheckBoxItem cbItem = null;
    for(int i=1;i<=ITEMS;i++)
    {
        cbItem = new CheckBoxItem();
        cbItem.Message = string.Format("Dette er nummer {0}", i);
        this.Controls[1].Controls.Add(cbItem);
    }
}

Her indsættes bare 10 forekomster af typen CheckBoxItem.
CheckBoxItem er en custom control som følger :

public class CheckBoxItem : Panel, INamingContainer
{
    protected CheckBox cb;
    protected Panel innerPanel;
    protected Label lblMessage;

    // property variable med default værdier
    private bool showPanel = false;
    private string message = "Default message";
    private string checkBoxText = "Default CheckBox tekst";       

    // angiver om panelet skal vises
    public bool ShowPanel
    {
        get{return (object)ViewState[this.UniqueID] != null ? (bool)ViewState[this.UniqueID] : showPanel;}
        set{ViewState[this.UniqueID]=value;}
    }
   
    // angiver teksten der indsættes i panelet
    public string Message
    {
        get{return message;}
        set{message = value;}
    }

    // teksten på checkboksen
    public string CheckBoxText
    {
        get{return checkBoxText;}
        set{checkBoxText = value;}
    }

    // alle kontroller tilføjes altid til kontroltræet
    protected override void CreateChildControls()
    {   
        // lidt styling
        this.CssClass = "CheckBoxItem";
       
        // for checkboxen
        cb = new CheckBox();
        cb.Text = this.CheckBoxText;
        cb.TextAlign = TextAlign.Left;
        cb.Checked = this.ShowPanel;
        cb.AutoPostBack = true;
        cb.CheckedChanged += new EventHandler(cb_CheckedChanged);
        this.Controls.Add(cb);

        // for innerPanel
        innerPanel = new Panel();
        innerPanel.CssClass = "CheckBoxItemInnerPanel";
        lblMessage = new Label();
        lblMessage.Text = this.Message;
        innerPanel.Controls.Add(lblMessage);
        this.Controls.Add(innerPanel);

        // vi sikrer at implementeringen på basen køres
        base.CreateChildControls ();
    }

    // overskrivning af RenderContent, så innerPanel kan skjules
    protected override void RenderContents(HtmlTextWriter writer)
    {
        foreach(Control c in this.Controls)
        {
            if(!(c is Panel))
                c.RenderControl(writer);
            else if (ShowPanel)
                c.RenderControl(writer);
        }
    }

    // håndtering af at brugeren klikker i en checkbox
    private void cb_CheckedChanged(object sender, EventArgs e)
    {
        this.ShowPanel = ((CheckBox)sender).Checked;
    }
}

// styles (men det kan jo være lidt ligemeget :o)
.CheckBoxItem
{
    border-style : solid;
    border-width : 1px;
    border-color : Navy;
    background-color : Silver;
    font-family : Verdana;
    font-size : x-small;
    width : 200px;
}

.CheckBoxItemInnerPanel
{
    border-style : None;
    background-color : LightBlue;
    font-size : xx-small;
    width : 100%;
    height : 50px;
}

Det du skal lægge mærke til er, at kontrollen selv vedligeholder sin tilstand (i det her tilfælde en bolsk værdi) i viewstate.
Desuden konstrueres den komplette kontrol hver gang, og panelet skjules bare i forbindelse med renderingen.

Nu er det her jo bare et eksempel, og ikke nødvendigvis den bedste måde at gøre det på, men jeg håber det er lidt illustrativt, og du skulle kunne afvikle det umiddelbart.

Jeg tror du vil få kunne få noget ud af søge i dokumentationen efter "page lifecycle", og "maintaining state ".

Jeg håber du kan bruge det til noget - ellers må du skrive tilbage.

Mvh
Avatar billede fileto Seniormester
11. juli 2004 - 01:05 #4
Mange tak for inputtet, jeg skal lige studere din kode, så vender jeg tilbage.
Avatar billede fileto Seniormester
11. juli 2004 - 01:11 #5
Rating er initialiseret som en teksbox, men det hvar bare for at prøve et eller andet.

TextBox rating = new TextBox();
Avatar billede fileto Seniormester
11. juli 2004 - 15:18 #6
Hej snepnet

Nu har jeg prøvet at danne alle kontroller i pageload, men når jeg danner panelet i pageload så vises alle checkboxe men kun den sidste panel kontrol, alle andre panelkontroller er væk.

#code start
CheckBox chkFeature = new CheckBox();
Panel[] lstFeature = new Panel[5];
TextBox rating = new TextBox();

private void Page_Load(object sender, System.EventArgs e)
{
    for (features=1;features<numberOfSelectedFeatures+1;features++)
    {
        spacer = space * (features-1);
        buttonTopBase = buttonTopBase + space;
        // this is a new instance of the cehckbox object?
        chkFeature = new CheckBox();
        chkFeature.Height = 20;
        chkFeature.Width = 200;
        chkFeature.Style.Add("top", "" + (baseTop+spacer) + "px");
        chkFeature.Style.Add("left", "" + FeaturelistCol + "px");
        chkFeature.Style.Add("position", "absolute");
        chkFeature.Text = featureName[features-1];
        chkFeature.AutoPostBack = true;
        chkFeature.ID = "" + ((features-1)+1) + "";

        // feature
        if (searchmethod == "features")
        {
            chkFeature.CheckedChanged += new EventHandler(FeaturePannel);
        }
        // featuredeail checkbox
        if (searchmethod == "details")
        {
            chkFeature.CheckedChanged += new EventHandler(FeaturedetailsPannel);
        }

        plhSearchHolder.Controls.Add(chkFeature);

        if (searchmethod == "features")
        {
            lstFeature[features-1] = new Panel();

            lstFeature[features-1].Controls.Add(rating);

            lstFeature[features-1].Height = featuredetailsHeight;
            lstFeature[features-1].Width = featuredetailsWith;
            lstFeature[features-1].Style.Add("top", "" + (baseTop+(space*(features-1))) + "px");
            lstFeature[features-1].Style.Add("left", "" + featuredetailCol + "px");
            lstFeature[features-1].Style.Add("position", "absolute");
            lstFeature[features-1].EnableViewState = true;
            lstFeature[features-1].DataBind();
            lstFeature[features-1].HorizontalAlign = HorizontalAlign.Left;
            lstFeature[features-1].Enabled = true;
            lstFeature[features-1].Visible = true;
            this.plhSearchHolder.Controls.Add(lstFeature[features-1]);
        }

    }
}
#code slut

Hvad kan dette mon skyldes?
Avatar billede snepnet Nybegynder
11. juli 2004 - 18:53 #7
At du kun har én enkelt TextBox (rating) at vise frem.

Du indsætter den således her :
lstFeature[features-1].Controls.Add(rating);

Du kan checke om det ikke er det der er problemet, hvis du gør sådan her :
lstFeature[features-1].Controls.Add(new CheckBox());
Avatar billede fileto Seniormester
11. juli 2004 - 22:06 #8
Hej snepnet.
Der virker når man bruger :
lstFeature[features-1].Controls.Add(new TextBox());

Tak for hjælpen :-)
Post lige et svar for point.
Mvh
Avatar billede fileto Seniormester
11. juli 2004 - 22:09 #9
En sidste kommentar.

Det undrer mig nu stadig at min kode med checkboxlister virkede fint. Den er bygget op på samme måde som det der ikke virkede for mig. (beskrevet ovenfor).

Denne kode således ud

#code start
  CheckBoxList[] lstFeaturedetails = new CheckBoxList[5];

  chkFeature.CheckedChanged += new EventHandler(FeaturedetailsPannel);

  lstFeaturedetails[features-1] = new CheckBoxList();
  plhSearchHolder.Controls.Add(lstFeaturedetails[features-1]);


    private void FeaturedetailsPannel(object sender, System.EventArgs e)
    {
      CheckBox chkFeat = new CheckBox();
      chkFeat = (CheckBox)sender;

      string fId = chkFeat.ID;
      int featix;
      featix = Int32.Parse(fId);

      //      populate Featuredetail list
      string sqlString =  "sqlstring";
      ArrayList FeaturedetailSelection = new ArrayList();
      if (chkFeat.Checked)
      {
        MovieDb.MdbPassSqlsCommand(sqlString);
        MovieDb.MdbConnectionOpen();
        MovieDb.MdbExecuteReader();
        pSelection featureDetails = new pSelection();
        while (MovieDb.MdbDataRead())
        {
          featureDetails = new pSelection();
          featureDetails.sName = MovieDb.MdbGetString("FeatureDetailname");
          featureDetails.sValue = MovieDb.MdbGetInt("Id");
          FeaturedetailSelection.Add (featureDetails);
        }
        MovieDb.MdbConnectionClose();
      }
      else
      {
        FeaturedetailSelection.Remove(sender);
      }
      lstFeaturedetails[featix-1].Height = featuredetailsHeight;
      lstFeaturedetails[featix-1].Width = featuredetailsWith;
      lstFeaturedetails[featix-1].Style.Add("top", "" + (baseTop+(space*(featix-1))) + "px");
      lstFeaturedetails[featix-1].Style.Add("left", "" + featuredetailCol + "px");
      lstFeaturedetails[featix-1].Style.Add("position", "absolute");
      lstFeaturedetails[featix-1].EnableViewState = true;
      lstFeaturedetails[featix-1].RepeatDirection = RepeatDirection.Horizontal;

      lstFeaturedetails[featix-1].DataTextField = "sName"; // Navnet på den property på dine dataobjekter der skal være tekst
      lstFeaturedetails[featix-1].DataValueField = "sValue"; //Navnet på den property på dine dataobjecter der skal være value
      lstFeaturedetails[featix-1].DataSource = FeaturedetailSelection;
      lstFeaturedetails[featix-1].DataBind();
    }

Dette kode adskilder sig kun ved at det er en checkboxliste og ikke en panel jeg bruger og her bruger jeg også DataSource istedet for Controls.Add.

Har du nogen umidelbar bud på hvorfor man kan gøre dette med checkboxliste og ikke med panel?
Det er bare af nysgærighed så det er mere hvis du har et umidelbart bud så jeg kunne lære lidt af dette.
Mvh
Avatar billede fileto Seniormester
11. juli 2004 - 22:21 #10
Jeg tror jeg har fundet ud af hvorfor.

Når jeg danner checkboxlister erklærer jeg objectet på page loadtidpunket.
lstFeaturedetails[features-1] = new CheckBoxList();

Men det er jo også det jeg gør med panels. Men her har jeg 2 objecter jeg skal
erklere på pageload tidspunktet nemlig panel objectet og den kontrol som indgår.
i panel kontrollen.

Det er sjovt at se at når man bruger tid på at formulere et spørgsmål så finder man ofte selv svaret. :-)
Endu engang tak for de mange input
Mvh
Avatar billede snepnet Nybegynder
11. juli 2004 - 22:38 #11
Det var så lidt fileto.
(jeg var lige ved at skrive til dig da din nye meddelelse dukkede op i postkassen :o)

Vi skrives ved :o)

Mvh
Avatar billede snepnet Nybegynder
12. juli 2004 - 12:12 #12
Og det er sjovt... Altså det med når man skal formulere et spørgsmåls :o) - det virker tit.
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