【问题标题】:C# Hashtable does not retain valuesC# Hashtable 不保留值
【发布时间】:2009-07-26 05:03:55
【问题描述】:

我正在使用哈希表来存储键值对,并在 CreateDropDownLists() 方法中初始化此哈希表 (ddl_ht)。但是,当我在 SelectedIndexChanged 方法中检查“currentItem”的值时,该值为空。即使我检查了

的值

(字符串)ddl_ht[key[1]]

在我的监视窗口中,它显示一个值(非空)。你明白为什么这个 currentItem 是空的吗?

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;
        }

    }
}

【问题讨论】:

    标签: c# asp.net hashtable


    【解决方案1】:

    使用此设置,您将遇到各种线程问题。您的哈希表是静态的,您网站上的每次点击都会在一个新线程上创建您的类的新实例,该线程将尝试访问相同的哈希表 - 由于每个新的页面点击最初都会调用 CreateDropDownLists,因此您的将为页面的每个新用户重新初始化哈希表。

    【讨论】:

      【解决方案2】:

      您不应将 HashTable 存储为页面类的静态字段,因为它将在会话之间共享,因为 ASP.NET 中静态变量的生命周期在 appdomain 的生命周期内,请考虑将其存储在视图状态:

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

      【讨论】:

      • 如果创建了哈希表,该代码可能应该更改为存储哈希表。
      • @Simon:你是对的,但如果对象不在 ViewState 上,则返回 null 并提供一个 setter 可能更容易...检查编辑...
      • 感谢您提供示例代码。该解决方案进行了一些调整!这是我必须做的其他事情,这是非常基本的。在我的 PageLoad 中,我初始化了 ddl_ht,然后在 SelectedIndexChanged 方法中我必须将键转换为整数类型。这就是 currentItem 为空的原因。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多