2009-07-26 9 views
1

해시 테이블을 사용하여 키 - 값 쌍을 저장하고 CreateDropDownLists() 메서드에서이 해시 테이블 (ddl_ht)을 초기화합니다. 그러나 SelectedIndexChanged 메서드에서 "currentItem"값을 확인할 때이 값은 null입니다. 내 시계 창에C# Hashtable에 값이 저장되지 않습니다.

(문자열) ddl_ht [키 [1]]

의 값을 확인하고이 값 (null이 아닌)을 보여주고 있지만. 이 currentItem이 null 인 이유를 이해합니까?

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.SqlClient; 
using System.Diagnostics; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using ADONET_namespace; 

namespace AddFileToSQL 
{ 
    public partial class DataMatch : _Default 
    { 
     protected System.Web.UI.WebControls.PlaceHolder phTextBoxes; 
     protected System.Web.UI.WebControls.PlaceHolder phDropDownLists; 
     protected System.Web.UI.WebControls.Button btnAnotherRequest; 
     protected System.Web.UI.WebControls.Panel pnlCreateData; 
     protected System.Web.UI.WebControls.Literal lTextData; 
     protected System.Web.UI.WebControls.Panel pnlDisplayData; 

     protected static string inputfile2; 
     static string[] headers = null; 
     static string[] data = null; 
     static string[] data2 = null; 
     static DataTable myInputFile = new DataTable("MyInputFile"); 
     static string[] myUserSelections; 
     static Hashtable ddl_ht = new Hashtable(); 

     // Page Load 
     private void Page_Load(object sender, System.EventArgs e) 
     { 
      if (!Page.IsPostBack) 
      { 
       this.NumberOfControls = 0; 
      } 
     } 

     // Add DropDownList Control to Placeholder 
     private void CreateDropDownLists() 
     { 
      for (int counter = 0; counter < NumberOfControls; counter++) 
      { 
       DropDownList ddl = new DropDownList(); 
       SqlDataReader dr = ADONET_methods.DisplayTableColumns(targettable); 
       ddl.ID = "DropDownListID " + (counter + 1).ToString(); 
       ddl.DataTextField = "COLUMN_NAME"; 
       ddl.DataValueField = "COLUMN_NAME"; 
       ddl.DataSource = dr; 
       ddl.DataBind(); 

       //myUserSelections[counter] = ""; 

       ddl.AutoPostBack = true; 
       ddl.EnableViewState = true; //Preserves View State info on Postbacks 
       ddl.Style["position"] = "absolute"; 
       ddl.Style["top"] = 100 * counter + 80 + "px"; 
       ddl.Style["left"] = 250 + "px"; 
       ddl.SelectedIndexChanged += new EventHandler(SelectedIndexChanged); 
       ddl_ht.Add(counter, ddl.SelectedValue); 

       pnlDisplayData.Controls.Add(ddl); 
       pnlDisplayData.Controls.Add(new LiteralControl("<br><br><br>")); 
       pnlDisplayData.Visible = true; 
       pnlDisplayData.FindControl(ddl.ID); 
       // pnlDropDownList.FindControl(ddl.ID); 
       dr.Close(); 
      } 
     } 

     protected void SelectedIndexChanged(object sender, EventArgs e) 
     { 
      DropDownList ddl = (DropDownList)sender; 
      string[] value=(ddl.SelectedValue).Split(' '); 
      string[] key = ddl.ID.Split(' '); 
      string currentItem=(string)ddl_ht[key[1]]; 
      //if (String.IsNullOrEmpty(currentItem)) 
      //{ 
      // ddl_ht.Add(key[1], value[0]); 
      //} 
      if (currentItem != ddl.SelectedValue) 
      { 
       ddl_ht.Remove(key[1]); 
       ddl_ht.Add(key[1], ddl.SelectedValue); 
      } 
     } 

     // Add TextBoxes Control to Placeholder 
     private void RecreateDropDownLists() 
     { 
      for (int counter = 0; counter < NumberOfControls; counter++) 
      { 
       DropDownList ddl = new DropDownList(); 
       SqlDataReader dr = ADONET_methods.DisplayTableColumns(targettable); 

       ddl.ID = "DropDownListID " + (counter + 1).ToString(); 
       ddl.DataTextField = "COLUMN_NAME"; 
       ddl.DataValueField = "COLUMN_NAME"; 
       ddl.DataSource = dr; 
       ddl.DataBind(); 
       myUserSelections[counter] = ""; 
       dr.Close(); 

       ddl.AutoPostBack = true; 
       ddl.EnableViewState = true; //Preserves View State info on Postbacks 
       ddl.Style["position"] = "absolute"; 
       ddl.Style["top"] = 100 * counter + 80 + "px"; 
       ddl.Style["left"] = 250 + "px"; 
       ddl.SelectedIndexChanged += new EventHandler(SelectedIndexChanged); 
       pnlDisplayData.Controls.Add(ddl); 
       pnlDisplayData.Controls.Add(new LiteralControl("<br><br><br>")); 
      } 
     } 

     // Create TextBoxes and DropDownList data here on postback. 
     protected override void CreateChildControls() 
     { 
      // create the child controls if the server control does not contains child controls 
      this.EnsureChildControls(); 

      // Creates a new ControlCollection. 
      this.CreateControlCollection(); 

      // Here we are recreating controls to persist the ViewState on every post back 
      if (Page.IsPostBack) 
      { 
       RecreateDropDownLists(); 
       RecreateLabels(); 
      } 
      // Create these conrols when asp.net page is created 
      else 
      { 
       PopulateFileInputTable(); 
       CreateDropDownLists(); 
       CreateLabels(); 
      } 

      // Prevent child controls from being created again. 
      this.ChildControlsCreated = true; 
     } 

    } 
} 

답변

1

ASP.NET에서 정적 변수의 라이프 사이클이 응용 프로그램 도메인의 수명 내에 있기 때문에이 세션간에 공유되기 때문에 당신은 당신의 페이지 클래스의 정적 필드로 해시를 저장하지 말아야, ViewState에 저장하는 것이 좋습니다.

private Hashtable ddl_ht 
{ 
    get 
    { 
     return ViewState["ddl_ht"] as HashTable; 
    } 
    set 
    { 
     ViewState["ddl_ht"] = value; 
    } 
} 
+0

이 코드는 생성 된 경우 해시 테이블을 저장하는 것으로 변경해야합니다. – sisve

+0

@imim : 당신 말이 맞아요.하지만 객체가 ViewState에 없으면 null을 리턴하고, setter를 제공합니다. 편집을 확인하십시오 ... – CMS

+0

샘플 코드를 가져 주셔서 감사합니다. 이 솔루션은 두 번의 조작으로 작동했습니다! 여기에 내가해야 할 일은 꽤 기초가있다. 내 PageLoad에서는 ddl_ht를 초기화 한 다음 SelectedIndexChanged 메서드에서 키를 정수 유형으로 변환해야했습니다. 이것이 currentItem이 null 인 이유입니다. – salvationishere

3

이 설정에서는 모든 종류의 스레딩 문제가 발생합니다. 해시 테이블은 정적이며 웹 사이트의 모든 조회가 동일한 해시 테이블에 액세스하려고하는 새 스레드에서 클래스의 새 인스턴스를 만들고 페이지에 새로 방문 할 때마다 처음에 CreateDropDownLists이 호출되므로 해시 테이블은 페이지에 신규 사용자가있을 때마다 다시 초기화하십시오.

관련 문제