2010-06-17 20 views
1

我在动态生成控件,有时我想创建一个控件并让它忽略视图状态。例如,有时用户点击了一个按钮,表示他们需要加载不同的表单,所以我在回发时生成的控制树与原始控制树不同。这很好,除非我调用Controls.Add时,它会尝试将旧控件的视图状态加载到新控件中,如果控件树结构相似,并且我希望它们忽略该视图状态(并且也忽略回发值也用于输入控制)。如何忽略以前的特定控件请求的视图状态?

我可以做一些事情:设置控件的ID或允许我有条件地阻止它们获取先前请求的视图状态/回发数据?

编辑:如果我让控件的用户在回发处理程序中按需加载表单,当我调用Controls.Add时,不会应用回发数据(这看起来好像是ASP.NET中的一个缺陷,因为我会认为如果你打算通过Controls.Add应用视图状态数据,那么看起来你会在视图状态数据加载后自动应用回发数据。我碰到的真正问题是我的控件是非常动态的,但是我的控件的用户在它们的回发处理程序触发之前无法真正地告诉它该做什么,因为用户可以做的其中一件事是选择不同的表单通过一些链接按钮加载。所以直到回发处理程序运行,它们才知道uesr所请求的内容,因此可以要求我的控件加载某种形式。所以我必须要求他们做一些高价值的事情,例如将标识最后一种形式的formID保存到会话变量中,然后在OnInit中他们通过属性告诉我的表单旧的formID是什么。然后,我的控件在OnLoad中加载表单,以便它可以使用视图状态和回发数据,然后在程序员的回发处理程序中,他们可以选择清除表单并根据需要加载其他表单。编辑2:FYI为表单的每个控件生成ID的工作很好,所以我想我可以消除旧表单的无意义加载,直到程序员请求在其回发处理程序中加载表单。但正如我上面提到的,我发现在回发数据处理发生后加载表单意味着数据丢失。而viewstate通过Contorls.Add加载,在页面生命周期中播放,似乎回传数据不会!所以看起来我在任何时候都被击败。

回答

2

给控制不同的ID将肯定会阻止ViewState被加载,这将是一种方式。

您也可以通过将其设置为“已禁用”来操纵控件的ViewStateMode属性。我不确定这是否阻止它加载(它绝对阻止它们保存视图状态),但是你可以尝试它。

+0

+1所有人,但我将其标记为答案,因为它直接解决了t他问关于忽视视图状态的问题。另外,即使我无法真正消除旧窗体的加载,设置ID仍然是我的解决方案的一部分,但每当我无法加载旧窗体时它将很重要,因为它不再有效,所以我可以忽略视图状态(我不会介入的长篇故事)。只需说谢谢。 – AaronLS 2010-06-17 20:40:29

1

您是否尝试过在添加新控件之前调用controls.clear?

UPDATE

我开始认为你是在页面生命周期错点产生的控制。你的流量是什么?

+0

我没有尝试过,而且我必须做的解决方法是在回发期间,动态生成以前的表单,以便它们可以使用视图状态/回发,然后调用Clear,然后创建新表单。如果我在调用clear之前没有生成旧窗体,那么这些控件并不存在于窗体中,因此viewstate仍然会等待并应用于新窗体,这通常会导致在控件类型为不同。 – AaronLS 2010-06-17 17:47:04

+0

我已经尝试过onload,oninit和各种组合的按需呼吁从我的控制(从一个回发处理程序,像一个按钮单击)调用的用户的函数调用,但无论何时调用Controls.Add然后asp.net通过已经发生的所有事件运行您的控件,因此无论如何viewstate都会被加载。所以在我的测试中,这两种方式似乎都没有什么区别。 – AaronLS 2010-06-17 19:46:18

+0

其实我说谎是因为如果我在生命周期中添加控件的时间太晚,回发数据就会丢失。请参阅编辑。 – AaronLS 2010-06-17 20:17:02

3

如果您和控制生命周期一起玩,您将会避免出现问题。基本上,只要你有一个渲染的控件,最好确保在下一个回传中重新创建控件,即使你不再需要它。回发的第一个目标应该是恢复之前的状态 - 只有那么你是否要对其进行更改。

我在这个答案最好地描述它:

Wrong state in Server Controls with same ID's when dynamically adding UserControl to UpdatePanel

+0

+1这是一个很好的回答问题 – NotMe 2010-06-17 20:31:11

+0

呃,我认为你是对的,这里面没有办法。 – AaronLS 2010-06-17 20:31:33

1

必须在回发的页面加载可生成动态控件:

protected void Page_Load(object sender, EventArgs e) 
    { 
     --Generate Dynamic Controls-- 
    } 

你需要做的是这样的:

protected override void OnInitComplete(EventArgs e) 
    { 
     base.OnInitComplete(e); 
    } 

    protected void OnInit() 
    { 
    --Generate Dynamic Controls-- 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 

    }