Asp.net DropDownList的SelectedValue无效,因为它不在项目列表中
以下是场景: DropDownList中的选择从列出可接受值的DB表绑定。在某一时间点,数值为: 一个 两个 三 四 稍后,可接受值列表将更改为: 一个 两个 四 五 但是,数据库中存储下拉列表值的字段在某些行上仍然包含值“三”。加载其中一行并设置SelectedValue时:Asp.net DropDownList的SelectedValue无效,因为它不在项目列表中,asp.net,drop-down-menu,list.selectedvalue,Asp.net,Drop Down Menu,List.selectedvalue,以下是场景: DropDownList中的选择从列出可接受值的DB表绑定。在某一时间点,数值为: 一个 两个 三 四 稍后,可接受值列表将更改为: 一个 两个 四 五 但是,数据库中存储下拉列表值的字段在某些行上仍然包含值“三”。加载其中一行并设置SelectedValue时: dd.SelectedValue = data.Field; // where data.Field == "Three" …将引发一个错误,说明“dd”具有无效的SelectedValue,因为它不在项目列表中 数据
dd.SelectedValue = data.Field; // where data.Field == "Three"
…将引发一个错误,说明“dd”具有无效的SelectedValue,因为它不在项目列表中
数据清理不是这里的选项。这会给客户带来问题,因为存储的值不是已创建数据的无效选项,而是新创建数据的无效选项
其他人是如何处理这种情况的?您可以在数据库表中为名为“Active”的下拉列表值添加一个额外的列,该下拉列表值可以是true,也可以是false。然后,不删除旧值,只需将其标记为非活动。您应该在客户的可接受值列表中设置foregin密钥约束,以确保在仍有一些客户使用某个值的情况下无法从表中删除该值
在客户端中,您可以以不同的颜色显示正在使用非活动类型的客户,并且具有一种验证方法,该方法不允许您将客户从活动类型更改为非活动类型,但允许具有非活动类型的客户保留该设置。假设
data.Field
实际上是一个字符串,我会:
ListItem itemToSelect = dd.Items.FindByText(data.Field);
if(itemToSelect != null)
{
dd.SelectedItem = itemToSelect;
}
ListItemToSelect=dd.Items.FindByText(data.Field);
if(itemToSelect!=null)
{
dd.SelectedItem=要选择的项目;
}
所以旧值(在本例中为“三”)仍然存在于列表表中,但只是被停用,还是从表中完全删除 如果是前者,则设置两个单独的视图,一个仅包含活动项并用于新数据输入,另一个包含所有项并用于查看历史交易。因此,您必须将“历史上准确但现在失效”的值添加到下拉列表中,但是,您可以使用防止用户将此值保存回数据库。
RequiredFieldValidator的ControlToValidate
设置为要验证的DropDownList
,然后可以将InitialValue
属性设置为无效值。现在,在保存方法中,您可以在将页面保存到数据库之前检查bool页面。IsValid
。RequiredFieldValidator
上的消息可能类似于“此值不再可接受,因为…”
希望这有帮助 我们这里确实有这种情况 当这种情况发生时,我会手动将缺少的项目添加到dropdownlist,但会使用红色字体
如果用户尝试重新保存项目,则红色项目将被视为不活动且无效。然后必须从下拉列表中选择一个有效选项(非红色)。我们还有一个例行程序,首先检查项目的下拉列表,如果没有,则将其添加到列表中。与上面提到的Danny的想法相同,但我喜欢他添加红色的附加想法。尽管这是同样的想法,但我认为公布我们的全部日程安排是有价值的。它使用foreach遍历列表以查找值字符串。正如Justin所指出的,使用FindByText可以提高效率
protected bool SafeSetDropDownValue(DropDownList ddl, string value, string text, bool addItemIfNotFound)
{
// first make sure that drop down list has been data bound so that all the options are in there
ddl.DataBind();
// look for value in the list of dropdown values
// (can't use try/catch because exception doesn't happen until later)
bool found = false;
bool selected = true;
foreach (ListItem li in ddl.Items)
{
if (li.Value == value)
{
found = true;
}
}
if (found)
{
ddl.SelectedValue = value;
}
else
{
// the value wasn't in the list,
// so if addItem is true, then add the value to the list and then set the value
if (addItemIfNotFound)
{
ListItem li = new ListItem(text, value);
ddl.Items.Add(li);
ddl.SelectedValue = value;
}
else
{
// didn't find it and didn't add it
selected = false;
}
}
return selected;
}
谢谢到目前为止,我最喜欢这个解决方案。许多其他答案建议将此业务规则移动到DB(我不喜欢),或者导致当前值不显示,这在这种情况下是绝对不可接受的。尽管在这种特殊情况下,我还是允许重新保存,因为该值对于以前创建的数据仍然有效。只有新数据不应具有这些值。只有在旧数据上动态添加无效值这一事实充分解决了这个问题。迄今为止,我找到的最佳解决方案是+1。稍微精简的版本:
dd.SelectedIndex=dd.Items.IndexOf(dd.Items.FindByValue(value))代码>(另请参见。)