这篇,我将谈谈自己在开发自定义控件中的一些方法。
现在.net集成性太强,好多东西都不用自己去写,这让C++的相当羡慕,哈哈,所以那些麻烦的事(自定义控件)程序员都不去自己做,但是会底层的原理还是比较有好处的。
这篇,我将谈谈自己在开发自定义控件中的一些方法。
现在.net集成性太强,好多东西都不用自己去写,这让C++的相当羡慕,哈哈,所以那些麻烦的事(自定义控件)程序员都不去自己做,但是会底层的原理还是比较有好处的。
如果一个控件中有非常多的属性的话,你会选择全写在一个类中吗?
一般的人都会说不,因为这样的代码一看就晕,不好管理.如果能够按控件的特性来分开写的话,应该会好很多,这样在程序员调用的时候也好设置相关的属性.
前几篇文章我一直在做自定义分页控件.我们知道自定义分页控件如果做完善的话特别麻烦,理所当然的相应的属性也就特别多.所在根据我自己的实际情况,我把自己的分页控件分为三个类:
分页控件中部分类图结构:
1: CustomPagerSetting 分页控件相关设置
2 :CustomPagerText 分页控件相关文本设置
3:CustomInfoSectionSetting 分页控件自定义信息区设置
如此多的属性如果是放在一个类中那是相当麻烦的.为此我们可以将它们分开形成内嵌属性.
Code
分页控件相关设置#region 分页控件相关设置
[Description("分页控件相关设置"), Category("minjiang扩展"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty)]
public CustomPagerSetting CustomPager
{
get
{
// return this._CustomPager;
if (this._CustomPager == null)
{ this._CustomPager = new CustomPagerSetting(); }
if (IsTrackingViewState)
{
((IStateManager)this._CustomPager).TrackViewState();
}
return this._CustomPager;
}
set
{
this._CustomPager = value;
}
}
#endregion
分页控件相关文本设置#region 分页控件相关文本设置
[Description("分页控件相关文本设置"), Category("minjiang扩展"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty)]
public CustomPagerText PagerText
{
get
{
return this._PagerText ;
}
set
{
this._PagerText = value;
}
}
#endregion
分页控件相关文本设置#region 分页控件相关文本设置
[Description("分页控件自定义信息区设置"), Category("minjiang扩展"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty)]
public CustomInfoSectionSetting CustomInfoSection
{
get
{
return this._CustomInfoSection ;
}
set
{
this._CustomInfoSection = value;
this._CustomInfoSection.Owner = this;
}
}
#endregion
如何形成内嵌属性我现在不想多说,此时的控件属性如果是在代码中动态设置的话,如果页面没有回发事件,都是正常的,
但是如果有回发所有的属性都要重新赋值,否则所有的属性值都会丢失.
我们知道viewstate是不能保存复杂属性,就像上面的三个类,它只能保存简单属性,例如int,string等.
刚开始的时候我在
CustomPagerSetting为中修改,将里面的属性都用viewstate保存,但是编译通不过,提示不存在viewstate对象,但是在控件文件中是可以的,那是因为控件自己继承control类,类文件又不能继承control,所以我们需要自定义一个ViewState属性
Code
private bool _isTrackingViewState;
private StateBag _viewState;
protected StateBag ViewState
{
get
{
if (_viewState == null)
{
_viewState = new StateBag(false);
if (_isTrackingViewState) ((IStateManager)_viewState).TrackViewState();
}
return _viewState;
}
}
自定义类型状态管理,那么我们就必须接触到IStateManager这个接口实现这个接口要实现三个方法:
Code
自定义状态管理#region 自定义状态管理
bool IStateManager.IsTrackingViewState
{
get
{
return _isTrackingViewState;
}
}
void IStateManager.LoadViewState(object savedState)
{
if (savedState != null)
{
((IStateManager)ViewState).LoadViewState(savedState);
}
}
object IStateManager.SaveViewState()
{
object savedState = null;
if (_viewState != null)
{
savedState =
((IStateManager)_viewState).SaveViewState();
}
return savedState;
}
void IStateManager.TrackViewState()
{
_isTrackingViewState = true;
if (_viewState != null)
{
((IStateManager)_viewState).TrackViewState();
}
}
#endregion
这些MSN上都可查.这还不行,还要在控件类中实现自定义视图管理.
Code
自定义视图状态#region 自定义视图状态
protected override void LoadViewState(object savedState)
{
Pair p = savedState as Pair;
if (p != null)
{
base.LoadViewState(p.First);
((IStateManager)CustomPager).LoadViewState(p.Second);
return;
}
base.LoadViewState(savedState);
}
protected override object SaveViewState()
{
object baseState = base.SaveViewState();
object thisState = null;
if (this ._CustomPager != null)
{
thisState = ((IStateManager)this._CustomPager).SaveViewState();
}
if (thisState != null)
{
return new Pair(baseState, thisState);
}
else
{
return baseState;
}
}
protected override void TrackViewState()
{
if (this._CustomPager != null)
{
((IStateManager)this._CustomPager).TrackViewState();
}
base.TrackViewState();
}
#endregion
此时我们再试的时候,发现回发的时候,属性就不会丢失了。