艾伟:控件之ViewState

主题,控件的viewstate状态

一“七七八八”

有次,朋友开玩笑说,不知道什么时候,微软会取消viewstate,不再使用隐藏字段在服务器与客户端保存状态!虽然,可以使用客户端技术减少一些回传,但是,一些必要的服务器状态还是要保存的,现在网络带宽已经不是问题,所以在网络上适当的传递一些状态数据,还是可以容忍的!当然,如果终端是mobile,可以考虑把viewstate保存到服务器上!

二“误解viewstate”

    园子里,有不少描写viewstate的文字,也看了不少,知道Viewstate实现了IStateManager接口的一个属性和三个方法!刚接触“她”的时候,一直以为control对象直接实现了IStateManager接口,模糊的记得好象有几个LoadViewstate和SaveViewstate方法,也没有在意方法有没有override修饰!后来发现不是这样的,control并没有直接实现IStateManager接口,而是通过定义一个StateBar类型的Viewstate属性,委托Viewstate属性去管理状态,也就是让StateBar类型去真正实现状态的管理,这种方式可以使控件本身和viewState的实现完全分离!也许,这些经验,对高手谈不上是“经验”,希望刚入门的同仁能少走点弯路!

三“结合Style样式,浅谈Viewstate”

Viewstate属性能装载的数据类型比较有限,但是有些不能加载的类型怎么办呢?当然是重写
IStateManager了,然后WebControl委托给ControlStyle属性来管理状态,有点象WebControl
定义ViewState属性

还是从简单的入手吧,直接使用Style类型的状态管理
目标,定义一个文本框和一个按钮的复合控件
要点,分别给文本框和按钮各自定义样式,并提升她们为顶级样式属性
图一

图二 (文本框和按钮的样式)

图四 Demo
Code
using System;
using
 System.Web.UI;
using
 System.Web.UI.WebControls;
using
 System.ComponentModel;
using
 System.ComponentModel.Design;

namespace
 WebControlLibrary
{
    [
    DefaultEvent(
"Button"
),
    DefaultProperty(
"Text"
),
    
//Designer(typeof(WebControlLibrary.Design.CustomerControlDesigner))

    ]
    
    
public class
 WebCustomControl1 : CompositeControl
    
{
        
//声明变量

        private Button _button;
        
private
 TextBox _textBox;
        
private static readonly object EventButtonClick = new object
();
        
private
 Style _buttonStyle;
        
private
 Style _textBoxStyle;

        
//定义属性Text,用于指定按钮上的文字

        [
        Bindable(
true
),
        Category(
"Appearance"
),
        DefaultValue(
""
),
        Description(
"获取或设置显示显示在按钮上的文字"
)
        ]
        
public string
 Text
        
{
            
get

            
{
                EnsureChildControls();
                
return
 _button.Text;
            }


            
set
            
{
                EnsureChildControls();
                _button.Text 
=
 value;
            }

        }


        
//定义ButtonStyle属性
        [
        Category(
"Style"
),
        Description(
"设置Button的样式属性"
),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(
true
),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        
public virtual
 Style ButtonStyle
        
{
            
get

            
{
                
if (_buttonStyle == null
)
                
{
                    _buttonStyle 
= new
 Style();
                    
if
 (IsTrackingViewState)
                    
{
                        ((IStateManager)_buttonStyle).TrackViewState();
                    }

                }

                
return _buttonStyle;
            }

        }


        
//定义TextStyle属性
        [
        Category(
"Style"
),
        Description(
"设置TextBox的样式属性"
),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(
true
),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        
public virtual
 Style TextBoxStyle
        
{
            
get

            
{
                
if (_textBoxStyle == null
)
                
{
                    _textBoxStyle 
= new
 Style();
                    
if
 (IsTrackingViewState)
                    
{
                        ((IStateManager)_textBoxStyle).TrackViewState();
                    }

                }

                
return _textBoxStyle;
            }

        }


        
//重写Controls属性
        public override ControlCollection Controls
        
{
            
get

            
{
                EnsureChildControls();
                
return base
.Controls;
            }

        }


        
//重写CreateChildControls方法,将子控件添加到复合控件中
        protected override void CreateChildControls()
        
{
            Controls.Clear();
            _button 
= new
 Button();
            _textBox 
= new
 TextBox();
            _button.ID 
= "btn"
;
            _button.CommandName 
= "ButtonClick"
;
            
this
.Controls.Add(_button);
            
this
.Controls.Add(_textBox);
        }


        
//重写Render方法,呈现控件中其他的HTML代码
        protected override void Render(HtmlTextWriter output)
        
{
            
//AddAttributesToRender(output);

            if (_textBoxStyle != null)
            
{
                _textBox.ApplyStyle(TextBoxStyle);
            }

            
if (_buttonStyle != null)
            
{
                _button.ApplyStyle(ButtonStyle);
            }

            output.AddAttribute(HtmlTextWriterAttribute.Border, 
"0px");
            output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, 
"5px"
);
            output.AddAttribute(HtmlTextWriterAttribute.Cellspacing, 
"0px"
);
            output.RenderBeginTag(HtmlTextWriterTag.Table);
            output.RenderBeginTag(HtmlTextWriterTag.Tr);
            output.RenderBeginTag(HtmlTextWriterTag.Td);
            _textBox.RenderControl(output);
            output.RenderEndTag();
            output.RenderBeginTag(HtmlTextWriterTag.Td);
            _button.RenderControl(output);
            output.RenderEndTag();
            output.RenderEndTag();
            output.RenderEndTag();
        }


        
//事件处理
        public event EventHandler ButtonClick
        
{
            add
            
{
                Events.AddHandler(EventButtonClick, value);
            }

            remove
            
{
                Events.RemoveHandler(EventButtonClick, value);
            }

        }


        
protected virtual void OnButtonClick(EventArgs e)
        
{
            EventHandler buttonClickHandler 
=
 (EventHandler)Events[EventButtonClick];
            
if (buttonClickHandler != null
)
            
{
                buttonClickHandler(
this
, e);
            }

        }


        
protected override bool OnBubbleEvent(object sender, EventArgs e)
        
{
            
bool handled = false
;
            
if (e is
 CommandEventArgs)
            
{
                CommandEventArgs ce 
=
 (CommandEventArgs)e;
                
if (ce.CommandName == "ButtonClick"
)
                
{
                    OnButtonClick(EventArgs.Empty);
                    handled 
= true
;
                }

            }

            
return handled;
        }


        
//样式状态管理,重写3个相关方法
        protected override void LoadViewState(object savedState)
        
{
            
if (savedState == null
)
            
{
                
base.LoadViewState(null
);
                
return
;
            }

            
if (savedState != null)
            
{
                
object[] myState = (object
[])savedState;
                
if (myState.Length != 3
)
                
{
                    
throw new ArgumentException("无效的ViewState"
);
                }

                
base.LoadViewState(myState[0]);
                
if (myState[1!= null
)
                
{
                    ((IStateManager)TextBoxStyle).LoadViewState(myState[
1
]);
                }

                
if (myState[2!= null)
                
{
                    ((IStateManager)ButtonStyle).LoadViewState(myState[
2
]);
                }

            }

        }


        
protected override object SaveViewState()
        
{
            
object[] myState = new object[3
];
            myState[
0= base
.SaveViewState();
            myState[
1= (_textBoxStyle != null? ((IStateManager)_textBoxStyle).SaveViewState() : null
;
            myState[
2= (_buttonStyle != null? ((IStateManager)_buttonStyle).SaveViewState() : null
;

            
for (int i = 0; i < 3; i++
)
            
{
                
if (myState[i] != null
)
                
{
                    
return
 myState;
                }

            }

            
return null;
        }


        
protected override void TrackViewState()
        
{
            
base
.TrackViewState();

            
if (_buttonStyle != null
)
            
{
                ((IStateManager)_buttonStyle).TrackViewState();
            }

            
if (_textBoxStyle != null)
            
{
                ((IStateManager)_textBoxStyle).TrackViewState();
            }

        }

    }

}

Demo比较简单,在类顶部定义了两个Style类型的属性,然后重写维护状态的三个方法一个属性
注意
1.这里并不是直接重写IStateManager接口
2.重写 SaveViewState 方法以将附加样式属性保存到
ViewState
3.重写 LoadViewState 方法以自定义从 ViewState 的附加样式属性的还原
4.必须以添加它们的相同顺序检索
四 控件状态的细节远不只是这些,有不妥当的地方,还望同仁指出...(后续)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值