这篇,我将谈谈自己在开发自定义控件中的一些方法。
现在.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
此时我们再试的时候,发现回发的时候,属性就不会丢失了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)