検索

http://archive.cnblogs.com/a/1122213/ 2.2.2 Pair 类及ViewState的存储 Page 及所有控件的ViewState、ControlState都是存储在Pair类的实例中,了解Pair类及ViewState如何存储在Pair类中很重要。Pair定义的System.Web.UI中具体定义如下: public sealed cla

http://archive.cnblogs.com/a/1122213/


2.2.2   Pair类及ViewState的存储

Page及所有控件的ViewState、ControlState都是存储在Pair类的实例中,了解Pair类及ViewState如何存储在Pair类中很重要。Pair定义的System.Web.UI中具体定义如下:

public sealed class Pair

{

    public object First;

    public object Second;

    public Pair();

    public Pair(object x, object y);

}

可以看出Pair类是用作存储两个相关对象的基本结构。Pair是一个工具类,使用它很容易形成一个树的数据结构。将__VIEWSTATE反序列化后就是一个Pair对象。这个对象即保存了控件之间的父子关系,也保存了ViewState信息。ViewState中的Key/Value对被转换为一个ArrayList对象保存在Pair对象中。下面我们来看看它是如何存储的。

ViewState机制由浅入深2
图3

图3是对Pair的一种图式表示方式,左边表示First对象,右边表示Second对象,根据这种图式方式,图4是利用Pair对象存储ViewState的结构,对于ControlState没有进行具体的展开。从savedState(Pair)开始采用了递归的存储方式,将所有控件的ViewState及关系存储起来,在Pair对象的First中存储ViewState数据,在Second中存储子控件的信息。

ViewState机制由浅入深2图4

2.2.3   Control中的处理

Page类继承自Control类,在实现ViewState机制的时候Page类中主要是涉及序列化和反序列化的工作,ViewState的保存、装载等功能都在Control类中实现由Page类来继承,
控件也都继承自Control类,下面对Control类中和ViewState机制相关的属性、方法进行介绍。
<strong>1)<span>     </span>ViewState属性</strong>
ViewState是Page及控件的一个属性,这个属性并不是在Page或控件中定义,它定义在System.Web.UI.Control类中。它的声明如下:

protected virtual StateBag ViewState{get}

由于所有服务器端的控件,用户自定义控件,及Page类都是继承自Control类,所以它们都会都具有一个protected的ViewState属性。这个ViewState属性在ViewState机制中
很重要,它用来存储控件需要记忆的一些数据。这些数据主要有两类,一类是需要记忆的控件的属性。另外一类是我们想利用ViewState机制来记住的一些数据,
比如我们在Web窗体中写如下的代码:

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!this.IsPostBack)

        {

            this.ViewState["Test"] = 0;

        }

        else

        {

            this.ViewState["Test"]=int.Parse(this.ViewState["Test"].ToString()) + 1;

        }

<span>    }</span>
因为我们创建的Web窗体都是继承自Page类,所以在Web窗体中能否访问Page类的protected的ViewState属性。我们可以通过ViewState属性利用ViewState机制,让它帮助我们
记住一些信息。
ViewState属性的主要作用还是用来记住一些控件的属性值。ViewState属性和控件的其他属性有什么样的联系,才能够利用ViewState属性来记住他们呢?下面用Button类
的Text属性举例来说明,Text属性和ViewState属性是什么关系。Button.Text的定义如下:

public string Text

{

    get

    {

        string str = (string) this.ViewState["Text"];

        if (str != null)

        {

            return str;

        }

        return string.Empty;

<span>    }</span>

    set

    {

        this.ViewState["Text"] = value;

<span>    }</span>

}

通过上面的代码我们可以看出Button.Text属性的值实际上和ViewState中Key为“Text”的Value是关联的。当然Button类的其他属性也是类似的方式,
只是对应ViewState中Key不同而已。这样只要ViewState的值能够被记忆,那么Button类的属性也就能够被记忆住了。记忆ViewState的方法就是在Page. SaveAllState中
将所有控件的ViewState属性生成一个对象(这是一个特殊的对象,它是一个树状态的存储了所有控件的ViewState属性),然后将这个对象序列化为字符串,发送到客户端。
在下次请求的时候,将这个字符串发送给服务器,在Page.LoadAllState中将这个字符串反序列化为一个对象,将这个对象中存储的各个控件的ViewState属性,
加载给各个控件的ViewState属性。当我们访问控件的属性的时候就实现了对控件属性的记忆,之前设置的控件属性没有丢失。
<strong>2)<span>     </span>LoadViewStateByID属性</strong>

LoadViewStateByID的声明如下:

protected bool LoadViewStateByID{get}

LoadViewStateByID获取一个值,该值指示控件是否通过ID方式加载其视图状态。默认情况下是通过索引方式加载视图状态,索引方式是依赖子控件在父控件的Controls集合中位置。ID方式会根据ID查找控件,效率比较低些,但是有些情形必须使用这种方式比如延迟创建子控件时。

<strong>3)<span>     </span>EnableViewState属性</strong>
EnableViewState是一个bool类型的属性,来决定当前控件的ViewState机制是否可用。其声明如下:

public virtual bool EnableViewState{get,set}

<strong>4)<span>     </span>LoadViewStateRecursive</strong>
LoadViewStateRecursive的声明如下:
<span>internal</span><span>void</span><span> LoadViewStateRecursive(<span>object</span> savedState)</span>
Page.LoadAllState中调用Control.LoadViewStateRecursive,传入的参数savedState是一个Pair类型的对象,Pair.Fisrt中保存当前控件的ViewState,
Pair.Second中保存子控件的ViewState。对于EnableViewState为true时,先通过调用Control.LoadViewState(savedState.First)装载当前控件的ViewState。
之后根据LoadViewStateByID<span>属性,装载子控件的ViewState。</span>如果LoadViewStateByID<span>属性为true调用Control.</span>LoadChildViewStateByID(savedState.Second)<span>,否则调用</span>
<span>Control.</span>LoadChildViewStateByIndex(savedState.Second)。savedState.Second是一个ArrayList类型的对象。

Control.LoadViewState的声明如下:

<span>protected</span><span> <span>virtual</span> void LoadViewState(object savedState)</span>
在Control.LoadViewState中并没有自己实现装载当前控件的ViewState,而是通过ViewState.LoadViewState(savedState)来实现,下面会介绍StateBag的LoadViewState方法。
LoadChildViewStateByID<span>的声明如下:</span>
<span>internal</span><span> void LoadChildViewStateByID(<span>ArrayList</span> childState)</span>
参数childState是ArrayList类型,childState中存储了当前控件的所有子控件的信息。它的格式是首先是一个控件的ID,其后是这个控件的Pair对象。对childState进行循环
,循环中取得控件的ID,根据ID找到控件调用这个控件的LoadViewStateRecursive方法。示意代码如下:

for (int i = 0; i 2)

    {

        string id = (string) childState[i];

        object savedState = childState[i + 1];

       Control control = this.FindControl(id);

        control.LoadViewStateRecursive(savedState);

<span>    }</span>

<span>LoadChildViewStateByIndex</span><span>的声明如下:</span>

internal void LoadChildViewStateByIndex(ArrayList childState)

childState的存储格式是首先是一个控件的索引,其后是这个控件的Pair对象。根据索引访问访问这个控件,调用其LoadViewStateRecursive方法,示例代码如下:

    for (int i = 0; i 2)

    {

        int num4 = (int) childState[i];

        object savedState = childState[i + 1];

        controls[num4].LoadViewStateRecursive(savedState);

     }

<strong>5)<span>     </span>LoadViewState</strong>

LoadViewState中直接调用ViewState的LoadViewState方法进行ViewState的装载,示意代码如下:

this.ViewState.LoadViewState(savedState);

<strong>6)<span>     </span>SaveViewStateRecursive</strong>
SaveViewStateRecursive的声明如下:

internal object SaveViewStateRecursive()

对于EnableViewState为true时,先调用Control.SaveViewState返回一个包含当前控件的ViewState信息的ArrayList类型对象x。之后对子控件进行递归处理获得一个ArrayList类型的对象z。它的格式是ID(String),savedState(Pair)或者Index(int)savedState(Pair)。最后创建一个Pair对象Pair(x, z)。示意代码如下:

object x = this.SaveViewState();

ArrayList z = null;

ControlCollection controls = this._occasionalFields.Controls;

int count = controls.Count;

bool loadViewStateByID = this.LoadViewStateByID;

for (int i = 0; i

{

          Control control = controls[i];

          object obj4 = control.SaveViewStateRecursive();

          if (loadViewStateByID)

                    z.Add(control.ID);

          else

                              z.Add(i);

          z.Add(obj4);

}

return new Pair(x, z);

<strong>7)<span>     </span>SaveViewState</strong>

SaveViewState中直接调用ViewState的SaveViewState方法进行ViewState的保存,示意代码如下:

return this.ViewState.SaveViewState();

<strong>8)<span>     </span>TrackViewState</strong>

在Control.InitRecursive中会调用Control.TrackViewState,因为Control.InitRecursive是被递归调用的,所以每个控件的TrackViewState都会在初始化阶段被调用到。Control.TrackViewState中之间调用ViewState的TrackViewState方法,示意代码如下:

this.ViewState.TrackViewState();



声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
MySQL:初心者が習得するための必須スキルMySQL:初心者が習得するための必須スキルApr 18, 2025 am 12:24 AM

MySQLは、初心者がデータベーススキルを学ぶのに適しています。 1.MySQLサーバーとクライアントツールをインストールします。 2。selectなどの基本的なSQLクエリを理解します。 3。マスターデータ操作:テーブルを作成し、データを挿入、更新、削除します。 4.高度なスキルを学ぶ:サブクエリとウィンドウの関数。 5。デバッグと最適化:構文を確認し、インデックスを使用し、選択*を避け、制限を使用します。

MySQL:構造化データとリレーショナルデータベースMySQL:構造化データとリレーショナルデータベースApr 18, 2025 am 12:22 AM

MySQLは、テーブル構造とSQLクエリを介して構造化されたデータを効率的に管理し、外部キーを介してテーブル間関係を実装します。 1.テーブルを作成するときにデータ形式と入力を定義します。 2。外部キーを使用して、テーブル間の関係を確立します。 3。インデックス作成とクエリの最適化により、パフォーマンスを改善します。 4.データベースを定期的にバックアップおよび監視して、データのセキュリティとパフォーマンスの最適化を確保します。

MySQL:説明されている主要な機能と機能MySQL:説明されている主要な機能と機能Apr 18, 2025 am 12:17 AM

MySQLは、Web開発で広く使用されているオープンソースリレーショナルデータベース管理システムです。その重要な機能には、次のものが含まれます。1。さまざまなシナリオに適したInnodbやMyisamなどの複数のストレージエンジンをサポートします。 2。ロードバランスとデータバックアップを容易にするために、マスタースレーブレプリケーション機能を提供します。 3.クエリの最適化とインデックスの使用により、クエリ効率を改善します。

SQLの目的:MySQLデータベースとの対話SQLの目的:MySQLデータベースとの対話Apr 18, 2025 am 12:12 AM

SQLは、MySQLデータベースと対話して、データの追加、削除、変更、検査、データベース設計を実現するために使用されます。 1)SQLは、ステートメントの選択、挿入、更新、削除を介してデータ操作を実行します。 2)データベースの設計と管理に作成、変更、ドロップステートメントを使用します。 3)複雑なクエリとデータ分析は、ビジネス上の意思決定効率を改善するためにSQLを通じて実装されます。

初心者向けのMySQL:データベース管理を開始します初心者向けのMySQL:データベース管理を開始しますApr 18, 2025 am 12:10 AM

MySQLの基本操作には、データベース、テーブルの作成、およびSQLを使用してデータのCRUD操作を実行することが含まれます。 1.データベースの作成:createdatabasemy_first_db; 2。テーブルの作成:createTableBooks(idintauto_incrementprimarykey、titlevarchary(100)notnull、authorvarchar(100)notnull、published_yearint); 3.データの挿入:InsertIntoBooks(タイトル、著者、公開_year)VA

MySQLの役割:WebアプリケーションのデータベースMySQLの役割:WebアプリケーションのデータベースApr 17, 2025 am 12:23 AM

WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。

MySQL:最初のデータベースを構築しますMySQL:最初のデータベースを構築しますApr 17, 2025 am 12:22 AM

MySQLデータベースを構築する手順には次のものがあります。1。データベースとテーブルの作成、2。データの挿入、および3。クエリを実行します。まず、createdAtabaseおよびcreateTableステートメントを使用してデータベースとテーブルを作成し、InsertINTOステートメントを使用してデータを挿入し、最後にSelectステートメントを使用してデータを照会します。

MySQL:データストレージに対する初心者向けのアプローチMySQL:データストレージに対する初心者向けのアプローチApr 17, 2025 am 12:21 AM

MySQLは、使いやすく強力であるため、初心者に適しています。 1.MYSQLはリレーショナルデータベースであり、CRUD操作にSQLを使用します。 2。インストールは簡単で、ルートユーザーのパスワードを構成する必要があります。 3.挿入、更新、削除、および選択してデータ操作を実行します。 4. Orderby、Where and Joinは複雑なクエリに使用できます。 5.デバッグでは、構文をチェックし、説明を使用してクエリを分析する必要があります。 6.最適化の提案には、インデックスの使用、適切なデータ型の選択、優れたプログラミング習慣が含まれます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール