我发现在用户控件中保留属性值的唯一方法是使用ViewState。
public string Title {
get { return Convert.ToString(ViewState["Title"]); }
set { ViewState["Title"] = value; }
}
我不能说我对此印象非常深刻,因为用户控制的属性越多,你就越容易陷入ViewState。是否有更好的方法来坚持财产?
答案 0 :(得分:10)
这取决于。如果您需要将属性值保留在post-back之外,那么您将不得不使用ViewState或Session。由于这些控件是在每个帖子上重新创建的,否则你无法真正保持这种状态。
答案 1 :(得分:8)
使用ViewState存储用户控件的属性值完全没有问题。
您的声明“用户控件拥有的属性越多,您将在ViewState中保留的垃圾越多”并不一定如此。当然可以让ViewState跟踪控件属性的值,但不能将数据存储在__VIEWSTATE
隐藏表单字段变量中。
听起来很疯狂吗?有关ViewState如何工作的精彩文章,请参阅TRULY Understanding ViewState。
这取决于何时在其生命周期中初始化控件的属性。对于控件开始跟踪属性值的更改,View __VIEWSTATE
之后,ViewState将仅存储在隐藏的StateBag
字段中。在生命周期早期的控件的OnInit
方法中会发生这种情况,但是有一些技术可以提前设置属性值,但不会产生__VIEWSTATE
膨胀的成本,并且仍会为您提供所有好处。
请参阅链接的文章。它比我更清楚,更好地讨论了一切: - )
答案 2 :(得分:5)
您的问题正是ViewState的用途:要在回发后保留控件的属性,所以您的解决方案就可以了。
您可以将其保存在会话中,但这实际上只会给服务器带来负担。根据您拥有的用户数量,这可能会很快变得非常难看。
另请注意,如果使用会话,则必须进行一些内务处理。例如,如果要在同一页面上使用两次用户控件,则需要确保每个控件都使用唯一的会话变量。
答案 3 :(得分:2)
这不是太糟糕 - 这几乎就是内置控件如何工作,并且通常会导致预期的行为。最好的办法是,当您不需要在回发中保留这些值时,有选择地禁用ViewState。
您也可能想要查看ControlState - 它是一个人们无法禁用的独立“包”,并且用于GridView之类的东西,其中有些东西无法通过viewstate关闭,因为它打破了控制。
答案 4 :(得分:0)
您始终可以覆盖预期的SaveViewState
/ LoadViewState
方法:
public string Title { get; set; }
然后根据需要保存并加载:
protected override object SaveViewState()
{
// Save State as a cumulative array of objects.
object baseState = base.SaveViewState();
object[] allStates = new object[2];
allStates[1] = _title;
return allStates;
}
protected override void LoadViewState(object savedState)
{
if (savedState != null)
{
// Load State from the array of objects that was saved during SavedViewState.
object[] myState = (object[])savedState;
if (myState[0] != null)
base.LoadViewState(myState[0]);
if (myState[1] != null)
_title = (String)myState[1];
}
}
答案 5 :(得分:-1)
你试过静态属性吗?另外,请记住http是无状态的,因此您可以在每个page_load