ListItem 的 Attributes 在页面回发(PostBack)之间并不会保持视图状态?

偶然之间发现 ListItem 的 Attributes 在页面回发(PostBack)之间并不会保持视图状态,测试如下:
None.gif protected   void  Page_Load( object  sender, EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (!Page.IsPostBack) dot.gif{
InBlock.gif            ListItem item 
= new ListItem("hi""0");
InBlock.gif            item.Attributes[
"xvalue"= "x";
InBlock.gif            ListBox1.Items.Add(item);
InBlock.gif            item 
= new ListItem("hello""1");
InBlock.gif            item.Attributes[
"xvalue"= "y";
InBlock.gif            ListBox1.Items.Add(item);
ExpandedSubBlockEnd.gif        }

InBlock.gif        Response.Write(
"attributes:");
InBlock.gif        Response.Write(
"<br>");
ExpandedSubBlockStart.gifContractedSubBlock.gif        
foreach (ListItem item in ListBox1.Items) dot.gif{
InBlock.gif            IEnumerator iterator 
= item.Attributes.Keys.GetEnumerator();
ExpandedSubBlockStart.gifContractedSubBlock.gif            
while (iterator.MoveNext()) dot.gif{
InBlock.gif                
string key = iterator.Current.ToString();
InBlock.gif                Response.Write(key 
+ "=" + item.Attributes[key]);
InBlock.gif                Response.Write(
"<br>");
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }
首次加载呈现结果:
None.gif<select size="4" name="ListBox1" id="ListBox1">
None.gif    <option value="0"  xvalue="x">hi</option>
None.gif    <option value="1" xvalue="y">hello</option>
None.gif
None.gif</select>
但是,Postback 之后 attributes就丢失了。
DASM一下 ListItem :
None.gif .method assembly hidebysig instance  object  
None.gif        SaveViewState() cil managed
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
// Code size       89 (0x59)
InBlock.gif
  .maxstack  4
InBlock.gif  .locals init (
string V_0,
InBlock.gif           
string V_1)
InBlock.gif  IL_0000:  ldnull
InBlock.gif  IL_0001:  stloc.
0
InBlock.gif  IL_0002:  ldnull
InBlock.gif  IL_0003:  stloc.
1
InBlock.gif  IL_0004:  ldarg.
0
InBlock.gif  IL_0005:  ldfld      
bool System.Web.UI.WebControls.ListItem::textisdirty
InBlock.gif  IL_000a:  brfalse.s  IL_0013
InBlock.gif  IL_000c:  ldarg.
0
InBlock.gif  IL_000d:  call       instance 
string System.Web.UI.WebControls.ListItem::get_Text()
InBlock.gif  IL_0012:  stloc.
0
InBlock.gif  IL_0013:  ldarg.
0
InBlock.gif  IL_0014:  ldfld      
bool System.Web.UI.WebControls.ListItem::valueisdirty
InBlock.gif  IL_0019:  brfalse.s  IL_0022
InBlock.gif  IL_001b:  ldarg.
0
InBlock.gif  IL_001c:  call       instance 
string System.Web.UI.WebControls.ListItem::get_Value()
InBlock.gif  IL_0021:  stloc.
1
InBlock.gif  IL_0022:  ldarg.
0
InBlock.gif  IL_0023:  ldfld      
bool System.Web.UI.WebControls.ListItem::enabledisdirty
InBlock.gif  IL_0028:  brfalse.s  IL_003d
InBlock.gif  IL_002a:  ldloc.
0
InBlock.gif  IL_002b:  ldloc.
1
InBlock.gif  IL_002c:  ldarg.
0
InBlock.gif  IL_002d:  call       instance 
bool System.Web.UI.WebControls.ListItem::get_Enabled()
InBlock.gif  IL_0032:  box        [mscorlib]System.Boolean
InBlock.gif  IL_0037:  newobj     instance 
void System.Web.UI.Triplet::.ctor(object,
InBlock.gif                                                                  
object,
InBlock.gif                                                                  
object)
InBlock.gif  IL_003c:  ret
InBlock.gif  IL_003d:  ldarg.
0
InBlock.gif  IL_003e:  ldfld      
bool System.Web.UI.WebControls.ListItem::valueisdirty
InBlock.gif  IL_0043:  brfalse.s  IL_004d
InBlock.gif  IL_0045:  ldloc.
0
InBlock.gif  IL_0046:  ldloc.
1
InBlock.gif  IL_0047:  newobj     instance 
void System.Web.UI.Pair::.ctor(object,
InBlock.gif                                                               
object)
InBlock.gif  IL_004c:  ret
InBlock.gif  IL_004d:  ldarg.
0
InBlock.gif  IL_004e:  ldfld      
bool System.Web.UI.WebControls.ListItem::textisdirty
InBlock.gif  IL_0053:  brfalse.s  IL_0057
InBlock.gif  IL_0055:  ldloc.
0
InBlock.gif  IL_0056:  ret
InBlock.gif  IL_0057:  ldnull
InBlock.gif  IL_0058:  ret
ExpandedBlockEnd.gif}
  //  end of method ListItem::SaveViewState
None.gif

None.gif

SaveViewState确实没有保存Attributes,只是持久化了Text Value Enabled(这个还是按需)三个属性,
其实,ListItem.Attributes 内部都只是简单的如此实现,并没有像常见的有单独一个私有StateBag _attrState 与 AttributeCollection _attrCol出现,只是如果 _atrrCol如果为null,直接传了局部的StateBag 给AttributeCollection构造函数:
None.gif .method  public  hidebysig specialname instance  class  System.Web.UI.AttributeCollection 
None.gif        get_Attributes() cil managed
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
// Code size       32 (0x20)
InBlock.gif
  .maxstack  8
InBlock.gif  IL_0000:  ldarg.
0
InBlock.gif  IL_0001:  ldfld      
class System.Web.UI.AttributeCollection System.Web.UI.WebControls.ListItem::_attributes
InBlock.gif  IL_0006:  brtrue.s   IL_0019
InBlock.gif  IL_0008:  ldarg.
0
InBlock.gif  IL_0009:  ldc.i4.
1
InBlock.gif  IL_000a:  newobj     instance 
void System.Web.UI.StateBag::.ctor(bool)
InBlock.gif  IL_000f:  newobj     instance 
void System.Web.UI.AttributeCollection::.ctor(class System.Web.UI.StateBag)
InBlock.gif  IL_0014:  stfld      
class System.Web.UI.AttributeCollection System.Web.UI.WebControls.ListItem::_attributes
InBlock.gif  IL_0019:  ldarg.
0
InBlock.gif  IL_001a:  ldfld      
class System.Web.UI.AttributeCollection System.Web.UI.WebControls.ListItem::_attributes
InBlock.gif  IL_001f:  ret
ExpandedBlockEnd.gif}
  //  end of method ListItem::get_Attributes
None.gif

补记:
1。其实在 asp.net 1.x 设置ListItem.Attribtues,ListItem 并不会呈现这些 Attributes,已经被视为bug,虽然 2.0 做了改进,依然有问题。参见: ListControl Items and Attributes,
2。之前,为了给Checkbox设置一个客户端可用的 value ,偶尝试自定义了一个 带Value属性的扩展CheckBox控件,因为对于 value 这个Attribute,CheckBox内部好像对 ListItem 实现了强制性过滤。
3。早上baidu了一下,发现很多网友有类似的疑问,并提供了多种解决方案,
如何使CheckBoxList的Attributes属性生效(修改微软的一个bug).
非常有趣的是这个方案是通过重载Render方法,并将HtmlTextWriter输出文本,然后搜索匹配插入需要的 attribute
4。之前转载的一篇文章解决了这个问题:
[转]ListControl Items, Attributes, and ViewState
值得注意的是,这里  Scott Mitchell  采取的策略是分别扩展 DropDownList、CheckBoxlist等,而不是直接扩展 ListItem,减轻了工作量,详细见文章。
PS:其实很早都知道这个问题了,竟然直到现在才得以明白,惭愧 02.gif

转载于:https://www.cnblogs.com/Jinglecat/archive/2007/05/13/744423.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值