gpt4 book ai didi

c# - ASP复合控件子控件(单选按钮)丢失检查值

转载 作者:行者123 更新时间:2023-11-30 21:19:18 26 4
gpt4 key购买 nike

我正在使用动态创建的问题和选项在asp.net中进行测验控件。
主要控件基本上是容纳所有问题的容器。
在设计视图中,用户可以通过自定义集合编辑器添加问题。
每当我将问题添加到集合编辑器列表时,它都会为我生成一个问题标签。
每个问题对象内部都有一个标签和n个继承单选按钮控件的Option对象。这些选项对象中的每一个依次代表用户可以为每个问题选择的选项。

除了我现在位于我希望能够读取每个单选按钮的Checked值的部分之外,所有这些都有效。当我想在页面内实现此测验并检查问题时,我想在此页面上放置一个按钮并调用控件内的以下函数:

$

    public String checkQuestions()
{


if (questions != null)
{

foreach (Question question in questions)
{

options = question.readOptions();

int i = 0;
foreach (Option option in options)
{
testLabel.Text = option.Checked.ToString(); // test purposes only
}

}



}
return errors;

}


但是,一旦我选择了一个单选按钮并单击提交按钮,所有选项的Checked值将始终变为false。
基本上,它在回发后会丢失其检查的值,而我只是想解决它。
如果有人能指出我正确的方向,将不胜感激。

最佳答案

乍一看,我要检查两件事。首先,请确保您正在实现IPostBackDataHandler。这需要您实现两个方法,LoadPostDataRaisePostDataChangedEvent。在我的第一个猜测中,第一个可能是问题的根源。

手动处理回发

LoadPostData接受字符串postDataKeyNameValueCollection postCollection,并返回bool,指示值是否由于回发而更改。您不需要按照.Net最初的意图来实现此功能,例如,我创建了一个控件,其中包含多个单选按钮(出于不重要的原因,这里不能简单地将其作为RadioButtonList控件),因此确保它们均由属性string GroupName命名,并检查了该postCollectionGroupName

public bool LoadPostData(string postDataKey,
System.Collections.Specialized.NameValueCollection postCollection)
{
bool oldValue = _isChecked;

postCollection = HttpContext.Current.Request.Form; // See note below

_isChecked = (postCollection[this.GroupName] == this.Text);

return oldValue == _isChecked;
}


您会注意到我在这里重新定义 postCollection;这是因为 postCollection仅包含 HttpRequest.Form的一个子集,该子集与ASP.Net认为您的控件应关注的内容相对应。当您还在此处构建复合控件时,您可能希望这样做。

如果这在第一时间不起作用,请不要担心。值得逐步了解在调试模式下传递给此方法的内容(或将内容输出到 HttpContext.Trace,我通常会更容易找到它),以了解为什么您的代码不是您真正需要的代码。

快速警告

最后一件事: LoadPostData仅在发布的表单包含名称与您的控件的 UniqueID匹配的字段时调用。由于您的控件是一个复合控件,因此您可能需要对此稍加修饰,例如:

protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);

writer.WriteBeginTag("input");
writer.WriteAttribute("type", "hidden");
writer.WriteAttribute("name", this.UniqueID);
writer.WriteAttribute("value", "post");
writer.Write(" />");
}


这是一个肮脏的hack,但是会起作用; o)

手动处理视图状态

如果手动处理回发不能解决您的问题,则可能是您需要弄乱控件的viewstate。别担心,只要您遵循一些简单的规则,这看起来就不会那么可怕。

要手动处理视图状态,您只需要覆盖两个被称为 LoadViewStateSaveViewState的方法,显然就足够了。第一个使用viewstate的 object进行充气,另一个返回相同的 object结构。如果您使 SaveViewState覆盖返回包含某些内容的结构,则该结构需要保存所有需要持久保存的重要属性,然后只需在 LoadViewState方法中再次对其进行充气。

这是第一个狡猾的把戏出现的地方。您应该使用某些数据类型来保存viewstate,并且永远不要使用任何其他类型(因为其他类型的存储确实效率低下)。对您最有用的类型是 System.Web.UI.PairSystem.Web.UI.Triplet和我们的老朋友 System.Collections.ArrayListSystem.Collections.Hashtable。对和三元组仅存储两个或三个 object类型的值; ArrayList实际上是一个 List<object>

我猜想,在您的情况下,您可能想存储(1)布尔标志的ArrayList,存储单选按钮的“ checkedness”,或(2)字符串或整数的ArrayList,存储ID或索引。选中的单选按钮。

在前面提到的控件中,我只需要存储checkness和 Text属性,所以我的 LoadViewStateSaveViewState方法如下所示:

protected override void LoadViewState(object savedState)
{
Pair state = savedState as Pair;

if (state != null)
{
_isChecked = state.First as Nullable<bool> ?? false;
this.Text = state.Second as string;
}
}


protected override object SaveViewState()
{
return new Pair(_isChecked, this.Text);
}


再次,如果这第一次不起作用,则几乎可以肯定,您将逐步浏览代码或将其放入Trace中。重要的是,如果您的视图状态已损坏或不存在,则您可能希望避免从这些方法引发Exception。

进一步阅读viewstate

当我弄乱viewstate时,有几篇非常有用的文章会为我加书签。第一个解释了为什么只应在视图状态中存储某些类型(例如,使用 ArrayListHashtable,而不是 List<T>Dictionary<TKey, TValue>),第二个是对所有这些的深入解释。 viewstate的东西实际上有效。


Don't let the BinaryFormatter get at it!
Truly understanding ViewState


我希望所有这些都可以解决您的问题。

关于c# - ASP复合控件子控件(单选按钮)丢失检查值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3854193/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com