鸟食轩的"SmartNavigation"补充版
关于asp.net的页面回滚后状态的保存一直是我头痛的问题.
我之前的处理方法是写一个函数来处理页面的定位问题.
这个函数也是参考了很多人的处理方法,自己再稍微处理了一下,代码如下:
#region Retain Events
protected void Retain()
{
StringBuilder saveScrollPosition = new StringBuilder ();
StringBuilder setScrollPosition = new StringBuilder ();
RegisterHiddenField("__SCROLLPOS", "0");
saveScrollPosition.Append("<script language='javascript'>");
saveScrollPosition.Append("document.body.id='MyBody';");
saveScrollPosition.Append("function saveScrollPosition() {");
saveScrollPosition.Append(" document.forms[0].__SCROLLPOS.value = MyBody.scrollTop;");
saveScrollPosition.Append("}");
saveScrollPosition.Append("MyBody.onscroll=saveScrollPosition;");
saveScrollPosition.Append("</script>");
RegisterStartupScript("saveScroll", saveScrollPosition.ToString());
if (Page.IsPostBack)
{
setScrollPosition.Append("<script language='javascript'>");
setScrollPosition.Append("function setScrollPosition() {");
setScrollPosition.Append(" MyBody.scrollTop = " + Request["__SCROLLPOS"] + ";");
setScrollPosition.Append("}");
setScrollPosition.Append("MyBody.onload=setScrollPosition;");
setScrollPosition.Append("</script>");
RegisterStartupScript("setScroll", setScrollPosition.ToString());
}
}
protected void Retain(string div)
{
string[] divs = {div};
Retain(divs);
}
protected void Retain(string[] divs)
{
StringBuilder saveScrollPosition = new StringBuilder ();
StringBuilder setScrollPosition = new StringBuilder ();
RegisterHiddenField("__SCROLLPOS", "0");
saveScrollPosition.Append("<script language='javascript'>");
saveScrollPosition.Append("document.body.id='MyBody';");
saveScrollPosition.Append("function saveScrollPosition() {");
saveScrollPosition.Append(" document.forms[0].__SCROLLPOS.value = MyBody.scrollTop;");
saveScrollPosition.Append("}");
saveScrollPosition.Append("MyBody.onscroll=saveScrollPosition;");
saveScrollPosition.Append("function saveDivDisplay() {");
foreach(string div in divs)
{
if ((div != null)||(div != ""))
{
RegisterHiddenField("__"+div,"");
saveScrollPosition.Append(" document.forms[0].__"+div+".value = "+div+".style.display;");
}
}
saveScrollPosition.Append("}");
saveScrollPosition.Append("MyBody.onmousedown=saveDivDisplay;");
saveScrollPosition.Append("</script>");
RegisterStartupScript("saveScroll", saveScrollPosition.ToString());
if (Page.IsPostBack)
{
setScrollPosition.Append("<script language='javascript'>");
setScrollPosition.Append("function setScrollPosition() {");
foreach(string div in divs)
{
if ((div != null)||(div != ""))
{
setScrollPosition.Append(" "+div+".style.display = '" + Request["__"+div] + "';");
}
}
setScrollPosition.Append(" MyBody.scrollTop = " + Request["__SCROLLPOS"] + ";");
setScrollPosition.Append("}");
setScrollPosition.Append("MyBody.onload=setScrollPosition;");
setScrollPosition.Append("</script>");
RegisterStartupScript("setScroll", setScrollPosition.ToString());
}
}
#endregion
protected void Retain()
{
StringBuilder saveScrollPosition = new StringBuilder ();
StringBuilder setScrollPosition = new StringBuilder ();
RegisterHiddenField("__SCROLLPOS", "0");
saveScrollPosition.Append("<script language='javascript'>");
saveScrollPosition.Append("document.body.id='MyBody';");
saveScrollPosition.Append("function saveScrollPosition() {");
saveScrollPosition.Append(" document.forms[0].__SCROLLPOS.value = MyBody.scrollTop;");
saveScrollPosition.Append("}");
saveScrollPosition.Append("MyBody.onscroll=saveScrollPosition;");
saveScrollPosition.Append("</script>");
RegisterStartupScript("saveScroll", saveScrollPosition.ToString());
if (Page.IsPostBack)
{
setScrollPosition.Append("<script language='javascript'>");
setScrollPosition.Append("function setScrollPosition() {");
setScrollPosition.Append(" MyBody.scrollTop = " + Request["__SCROLLPOS"] + ";");
setScrollPosition.Append("}");
setScrollPosition.Append("MyBody.onload=setScrollPosition;");
setScrollPosition.Append("</script>");
RegisterStartupScript("setScroll", setScrollPosition.ToString());
}
}
protected void Retain(string div)
{
string[] divs = {div};
Retain(divs);
}
protected void Retain(string[] divs)
{
StringBuilder saveScrollPosition = new StringBuilder ();
StringBuilder setScrollPosition = new StringBuilder ();
RegisterHiddenField("__SCROLLPOS", "0");
saveScrollPosition.Append("<script language='javascript'>");
saveScrollPosition.Append("document.body.id='MyBody';");
saveScrollPosition.Append("function saveScrollPosition() {");
saveScrollPosition.Append(" document.forms[0].__SCROLLPOS.value = MyBody.scrollTop;");
saveScrollPosition.Append("}");
saveScrollPosition.Append("MyBody.onscroll=saveScrollPosition;");
saveScrollPosition.Append("function saveDivDisplay() {");
foreach(string div in divs)
{
if ((div != null)||(div != ""))
{
RegisterHiddenField("__"+div,"");
saveScrollPosition.Append(" document.forms[0].__"+div+".value = "+div+".style.display;");
}
}
saveScrollPosition.Append("}");
saveScrollPosition.Append("MyBody.onmousedown=saveDivDisplay;");
saveScrollPosition.Append("</script>");
RegisterStartupScript("saveScroll", saveScrollPosition.ToString());
if (Page.IsPostBack)
{
setScrollPosition.Append("<script language='javascript'>");
setScrollPosition.Append("function setScrollPosition() {");
foreach(string div in divs)
{
if ((div != null)||(div != ""))
{
setScrollPosition.Append(" "+div+".style.display = '" + Request["__"+div] + "';");
}
}
setScrollPosition.Append(" MyBody.scrollTop = " + Request["__SCROLLPOS"] + ";");
setScrollPosition.Append("}");
setScrollPosition.Append("MyBody.onload=setScrollPosition;");
setScrollPosition.Append("</script>");
RegisterStartupScript("setScroll", setScrollPosition.ToString());
}
}
#endregion
用隐藏控件来保存值,但是有个问题,再回滚回来之后,页面再处理层的显示的时候会出现跳动.
看了鸟食轩的SmartNavigation系列文章,觉得非常的好用,解决了自己一直苦恼的问题,我想如果在控件里面自动循环出所有的层,然后控件呈现的时候把这些状态还原回去.
但是改了之后发现无法正常工作,估计还是自己太菜了.修改后的代码如下:
[DefaultProperty("Text")]
[ToolboxData("<{0}:ClientNavigation runat=server></{0}:ClientNavigation>")]
public class ClientNavigation : WebControl, INamingContainer, IPostBackDataHandler
{
public ClientNavigation() : base() {}
#region Properties
public int PositionTop
{
get
{
object obj = ViewState["PositionTop"];
return obj == null ? 0 : (int)obj;
}
set
{
ViewState["PositionTop"] = value;
}
}
public int PositionLeft
{
get
{
object obj = ViewState["PositionLeft"];
return obj == null ? 0 : (int)obj;
}
set
{
ViewState["PositionLeft"] = value;
}
}
public string DivDisplay
{
get
{
object obj = ViewState["DivDisplay"];
return obj == null ? "''": (string)obj;
}
set
{
ViewState["DivDisplay"] = value;
}
}
#endregion
protected override void Render(HtmlTextWriter writer)
{
this.RegisterClientScript();
writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden");
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.ClientID);
writer.AddAttribute(HtmlTextWriterAttribute.Value,string.Format("{0}:{1}:{2}", this.PositionTop,this.PositionLeft,this.DivDisplay));
//writer.AddAttribute(HtmlTextWriterAttribute.Value,string.Format("{0}:{1}", this.PositionTop,this.PositionLeft));
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
}
#region Client Script
private void RegisterClientScript()
{
const string REGISTER_KEY = "__ClientNavigate586787__";
string strScript = @"
<script language=""javascript"">
window.attachEvent('onload', CLN_ClientNavigation);
function CLN_ClientNavigation()
{{
var scrollTop = {0};
var scrollLeft = {1};
var scrollCount = 0;
var divdisplay = {2};
var dis = divdisplay.split('$$$');
do
{{
scrollCount ++;
window.scrollTo(scrollLeft, scrollTop);
}}
while(document.body.scrollTop < scrollTop && scrollCount < 10 );
var divs = document.getElementsByTagName('div');
for(i=0;i<divs.length;i++)
{{
if (dis[i+1] != null)
divs[i].style.cssText = dis[i+1];
}}
}}
document.body.onscroll = function()
{{
var body = document.body;
var dis = ' ';
var divs = document.getElementsByTagName('div');
for(i=0;i<divs.length;i++)
{{
dis = dis + '$$$' + divs[i].style.cssText;
}}
document.all.{3}.value = body.scrollTop + ':' + body.scrollLeft+ ':' + dis;
}}
</script>";
if ( !this.Page.IsStartupScriptRegistered(REGISTER_KEY) )
{
strScript = String.Format(strScript, this.PositionTop, this.PositionLeft, this.DivDisplay, this.ClientID);
//strScript = String.Format(strScript, this.PositionTop, this.PositionLeft, this.ClientID);
this.Page.RegisterStartupScript(REGISTER_KEY, strScript);
}
}
#endregion
#region IPostBackDataHandler interface
public void RaisePostDataChangedEvent()
{
// TODO: Add ClientNavigation.RaisePostDataChangedEvent implementation
}
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
bool modify = false;
string postData = postCollection[postDataKey];
if ( !StringHelper.IsEmpty(postData) )
{
string [] topleft = postData.Split(new char [] {':'});
int iPositionTop = int.Parse(topleft[0]);
int iPostionLeft = int.Parse(topleft[1]);
string sDiv = topleft[2];
if ( iPositionTop != this.PositionTop )
{
this.PositionTop = iPositionTop;
modify |= true;
}
if ( iPostionLeft != this.PositionLeft )
{
this.PositionLeft = iPostionLeft;
modify |= true;
}
if ( sDiv != this.DivDisplay)
{
this.DivDisplay = sDiv;
modify |= true;
}
}
return modify;
}
#endregion
}
[ToolboxData("<{0}:ClientNavigation runat=server></{0}:ClientNavigation>")]
public class ClientNavigation : WebControl, INamingContainer, IPostBackDataHandler
{
public ClientNavigation() : base() {}
#region Properties
public int PositionTop
{
get
{
object obj = ViewState["PositionTop"];
return obj == null ? 0 : (int)obj;
}
set
{
ViewState["PositionTop"] = value;
}
}
public int PositionLeft
{
get
{
object obj = ViewState["PositionLeft"];
return obj == null ? 0 : (int)obj;
}
set
{
ViewState["PositionLeft"] = value;
}
}
public string DivDisplay
{
get
{
object obj = ViewState["DivDisplay"];
return obj == null ? "''": (string)obj;
}
set
{
ViewState["DivDisplay"] = value;
}
}
#endregion
protected override void Render(HtmlTextWriter writer)
{
this.RegisterClientScript();
writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden");
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.ClientID);
writer.AddAttribute(HtmlTextWriterAttribute.Value,string.Format("{0}:{1}:{2}", this.PositionTop,this.PositionLeft,this.DivDisplay));
//writer.AddAttribute(HtmlTextWriterAttribute.Value,string.Format("{0}:{1}", this.PositionTop,this.PositionLeft));
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
}
#region Client Script
private void RegisterClientScript()
{
const string REGISTER_KEY = "__ClientNavigate586787__";
string strScript = @"
<script language=""javascript"">
window.attachEvent('onload', CLN_ClientNavigation);
function CLN_ClientNavigation()
{{
var scrollTop = {0};
var scrollLeft = {1};
var scrollCount = 0;
var divdisplay = {2};
var dis = divdisplay.split('$$$');
do
{{
scrollCount ++;
window.scrollTo(scrollLeft, scrollTop);
}}
while(document.body.scrollTop < scrollTop && scrollCount < 10 );
var divs = document.getElementsByTagName('div');
for(i=0;i<divs.length;i++)
{{
if (dis[i+1] != null)
divs[i].style.cssText = dis[i+1];
}}
}}
document.body.onscroll = function()
{{
var body = document.body;
var dis = ' ';
var divs = document.getElementsByTagName('div');
for(i=0;i<divs.length;i++)
{{
dis = dis + '$$$' + divs[i].style.cssText;
}}
document.all.{3}.value = body.scrollTop + ':' + body.scrollLeft+ ':' + dis;
}}
</script>";
if ( !this.Page.IsStartupScriptRegistered(REGISTER_KEY) )
{
strScript = String.Format(strScript, this.PositionTop, this.PositionLeft, this.DivDisplay, this.ClientID);
//strScript = String.Format(strScript, this.PositionTop, this.PositionLeft, this.ClientID);
this.Page.RegisterStartupScript(REGISTER_KEY, strScript);
}
}
#endregion
#region IPostBackDataHandler interface
public void RaisePostDataChangedEvent()
{
// TODO: Add ClientNavigation.RaisePostDataChangedEvent implementation
}
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
bool modify = false;
string postData = postCollection[postDataKey];
if ( !StringHelper.IsEmpty(postData) )
{
string [] topleft = postData.Split(new char [] {':'});
int iPositionTop = int.Parse(topleft[0]);
int iPostionLeft = int.Parse(topleft[1]);
string sDiv = topleft[2];
if ( iPositionTop != this.PositionTop )
{
this.PositionTop = iPositionTop;
modify |= true;
}
if ( iPostionLeft != this.PositionLeft )
{
this.PositionLeft = iPostionLeft;
modify |= true;
}
if ( sDiv != this.DivDisplay)
{
this.DivDisplay = sDiv;
modify |= true;
}
}
return modify;
}
#endregion
}
不知道是否有更好的解决方法.