【问题标题】:Cannot get values in OnInit event无法在 OnInit 事件中获取值
【发布时间】:2010-09-30 20:38:18
【问题描述】:

我了解事件在页面生命周期中发生的顺序,但这对我的情况没有帮助。我有一个复选框列表,它由一个充满表单的目录填充。当我选中表单名称旁边的框时,我希望它动态创建向导步骤并插入表单。

事件顺序: 初始化: GatherForms() - 检查目录并将所有表单名称加载到复选框中 LoadForms() - 检查“选定”会话并加载收集的表单

CheckBoxList:SelectedIndexChanged #AutoPost = true# PopulateForms() - 循环检查复选框并将它们添加到会话状态

当用户点击复选框时,它会进行回发并点击从会话中提取的 OnInit。问题是 PopulateForms() 尚未运行,因此即使已检查它也不会填充任何内容。如果我单击另一个项目,它将回发并出现。在刷新之前,我似乎无法从复选框中提取任何有用的信息,这意味着我无法立即看到表单出现。我也尝试过循环复选框,但不幸的是视图状态尚未发布。叹息。

有什么建议吗?

谢谢!

P.S:我不能使用 Request.Form[] 因为我必须从复选框中取出所有选定的项目。也许我可以,但我找不到方法:/

【问题讨论】:

    标签: c# asp.net dynamic wizard


    【解决方案1】:

    随着我在 ASP.NET 上的进步,这是一个常见的问题。

    使用动态控件,您会遇到在 OnInit 期间它们实际上不存在的问题。

    您可以做的是创建所有用户在 OnInit 期间可能看到的控件,并隐藏用户在代码中看不到的元素。页面将加载,所有可能的控件将被实例化(在代码中 - 不要担心这会出现在您的 HTML 中并使其膨胀),然后事件处理程序将触发,然后您可以处理设置向导的可见性。

    例如:

    public void OnInit(object sender, EventArgs e)
    {
        GatherForms();
        CreateWizardForm(); // creates a wizard and adds controls it will need
    }
    
    private void Checkbox_Checked(object sender, EventArgs e)
    {
        var checkBox = (CheckBox)sender;
        // append checkBox.SelectedValue to session state object of checkboxes
    }
    
    protected override void OnPreRender(object sender, EventArgs e)
    {
        if (/* Session checkboxes contain values */)
        {
            this.WizardForm.Visible = true;
            this.CheckboxList.Visible = false;
        }
    }
    

    如果您提前知道哪些控件将在向导表单中,则此方法有效。您可以在 OnPreRender 事件中更改这些控件的值、切换它们的可见性等,但您不能去添加新控件(例如 Controls.Add(new Button())) - 这必须在 OnInit 中完成事件。

    【讨论】:

    • 感谢您的 cmets,即使您正在加载 100 个表单,这是否是最聪明的方式?这会对性能造成重大影响吗?我不知道最终会添加多少表单,因为它们可以将它们放在一个文件夹中。所有这些对我来说都是新的,听起来它可能更容易实现。另外,我如何在这些论坛中粘贴代码?谢谢!
    • 您的想法与coales.net/post/2009/12/11/… 相结合使这变得更加容易。谢谢。
    • 100 个表格可能有也可能没有什么大不了的——这真的取决于你的情况。任何时候您可以重用控件(并且只需更改它们的标签、值和列表项)显然都是理想的,但您也可能会遇到不符合新要求的表单模板。如果您的表单很简单,并且每个表单都不需要复杂的计算或往返数据库,那么除非您处理该页面的大量流量,否则这可能没什么大不了的。
    • 谢谢你,我的项目现在正在飙升。在加载控件等方面使事情变得更加容易,并确保一切保持同步。幸运的是,这个项目没有涉及数据库,所以我很幸运,只是一群人创建了表单来输入应用程序以供访问。再次感谢!
    • 很高兴听到!不要忘记牢记可扩展性。如果您说的是在您的机器上填充页面的时间不到一秒钟,那就太好了。如果您的生产环境每秒有几十个请求,这可能会成为瓶颈。
    【解决方案2】:

    仅在 OnInit 中添加动态控件。在 PageLoad 之前不要进行任何填充/处理。您将通过这种方式保留您的价值观。

    【讨论】:

      【解决方案3】:

      动态控件的经典陷阱。

      老实说,最好的解决方案是使用 Request 值数组来查找您需要的信息,并忽略此特定情况下的生命周期内容。

      OnInit() 中,发布的值在那里,只是尚未被 ViewState 处理。所以你可以使用if (Request["myCheckBoxName"] == xxx) 来处理单个复选框,或者如果你可以使用Request["__EVENTTARGET"] 来获取导致回发的控件的名称。

      请参阅我的旧答案 here 以更深入地讨论该问题。

      【讨论】:

      • 是的,这是一场噩梦。第一次使用动态控件,我已经决定我不喜欢它们!我一直试图让这个简单的表单加载器工作一个半星期多,我觉得比我更菜鸟。谢谢你的帖子,我会看看我是否能解决这个请求。我将如何遍历复选框列表以查看请求检查的内容?
      • 您基本上需要检查每个复选框值以查看它是否已发布。复选框应该有某种命名方案 - 如果您在调试器中查看请求值,应该清楚如何解析被检查的名称。
      • 好的,所以我现在使用 EVENTTARGET 让它工作,它允许我编写 2 个不同的加载事件,这是我需要的。现在我的问题是当我单击复选框并将其删除时它会出错。给我一个视图状态错误。我今天将继续处理这件作品,但也许你会在我花一整天的时间处理它之前看到并出错,呵呵。感谢您的帮助。哎呀,我会发新帖子来显示代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      相关资源
      最近更新 更多