- PR -

【ASP.NET】カスタムコントロールの状態保存について

1
投稿者投稿内容
最大40
常連さん
会議室デビュー日: 2004/02/06
投稿数: 41
投稿日時: 2005-08-07 14:20
ASP.NET(C#)にてカスタムコントロールを作成しているのですが、状態の保存がうまくいかず、難儀しています。
作りたいコントロールは、
「テキストボックス+ボタンで構成される複合コントロールで、ボタンをクリックするとカレンダー(JavaScript製)が表示され、選択した日付がテキストボックスに入る」
というものです。

カレンダーの値をテキストボックスに選択した日付を入れるところまでは実現できるのですが、ポストバック後に入力されていた値を復元できずにいます。
MSDN等を参照すると、LoadPostDataで実現できるように思うのですが、LoadPostDataが発生しません。
コードは以下のようになっています。
"popUpCalendar"というのはカレンダーを表示する関数です。
コード:

public class ExtraPopUpCalendar
: System.Web.UI.WebControls.WebControl,IPostBackDataHandler
{
public String Text
{
get
{
object o = ViewState["Text"];
return (o == null) ? string.Empty : (string)o;
}
set { ViewState["Text"] = value; }

}

public virtual bool LoadPostData(string postDataKey,
NameValueCollection values)
{
Text = values[this.UniqueID];
return false;
}

public virtual void RaisePostDataChangedEvent()
{
}

/// <summary>
/// このコントロールをパラメータに指定された出力に書き出します。
/// </summary>
/// <param name="output"> 書き出す HTML ライタ </param>
protected override void Render(HtmlTextWriter output)
{
//Style属性を出力
foreach (string s in base.Attributes.Keys)
{
output.AddAttribute(s, base.Attributes[s]);
}

output.RenderBeginTag(HtmlTextWriterTag.Div);
//テキストボックス
output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID);
output.AddStyleAttribute("width", "80");
output.AddAttribute(HtmlTextWriterAttribute.Value, this.Text);
output.RenderBeginTag(HtmlTextWriterTag.Input);
//ボタン
output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "_btnShowCal");
output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + "_btnShowCal");
output.AddAttribute(HtmlTextWriterAttribute.Type, "button");
output.AddAttribute(HtmlTextWriterAttribute.Value, "▼");
output.AddAttribute("onclick", "javascript:return popUpCalendar(this, " + this.UniqueID + ", 'yyyy/mm/dd', '__doPostBack(\\'" + this.UniqueID + "\\')')");
output.RenderBeginTag(HtmlTextWriterTag.Input);
output.RenderEndTag();
output.RenderEndTag();
output.RenderEndTag();
}
}




ポストバック後のデータ復元の方法を教えていただけないでしょうか。
宜しくお願いします

[ メッセージ編集済み 編集者: 最大40 編集日時 2005-08-07 14:25 ]
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2005-08-08 13:55
Webカスタムコントロールですか?
ずいぶん前に作ったので間違って居たら申し訳ないです。
IPostBackDataHandlerを実装するのではないかと思うのですが、ご確認を。

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfSystemWebUIIPostBackDataHandlerClassTopic.asp



_________________
たつごろー
codeseek
こみゅぷらす
最大40
常連さん
会議室デビュー日: 2004/02/06
投稿数: 41
投稿日時: 2005-08-08 14:39
>たつごろーさん

レスポンス有難うございます

>IPostBackDataHandlerを実装するのではないかと思うのですが、ご確認を。

IPostBackDataHandlerは実装しているのですが、デバッグモードで追っていっても、
LoadPostDataを実行してくれません。

教えて頂いたページのサンプルと同じことをしてるつもりなんですが・・・
行き詰まってしまっています、、、
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2005-08-08 15:32
RaisePostDataChangedEvent
を書かないと駄目なんじゃないでしょうか。

_________________
たつごろー
codeseek
こみゅぷらす
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-08-08 15:47
こんにちは。

自分も試してないですが、勘で書きます。
(1)OnLoadをoverrideしてthis.Page.RegisterRequiresPostBack(this);と記述してみる
たぶん、これで発生するはず。

それでだめだったら、
(2)WebControlから派生しているのをControlから派生するようにする
これは自信ありません。

いくつか書籍やWebで見てみたけど、Controlから派生して書いているサンプルが多いです。
WebControlから派生している場合は、コンストラクタのbase側に基本となるHTMLタグを指定していました。
例:className : base("input")

何の違いがあるかわからないですが・・・
最大40
常連さん
会議室デビュー日: 2004/02/06
投稿数: 41
投稿日時: 2005-08-08 17:37
>たつごろー さん

>RaisePostDataChangedEvent
これはポストバック後にデータが変わっている場合に発生するイベントなので、
値を保持するだけの場合は必要ないと思うのですが、何か処理が必要なんでしょうか。

たつごろーさんに教えて頂いたページのサンプルをそのまま使ってみたのですが、
ポストバックすると入力した内容が消えてしまいました、、、。
LoadPostDataはそもそも「ポストバック後にデータを復元する」
目的で使うものではない気がしてきました。。。

>nodera さん

>(1)OnLoadをoverrideしてthis.Page.RegisterRequiresPostBack(this);と記述してみる

を追加したところ、とりあえずLoadPostDataは通ってくれるようになりました。
が、valuesの中に肝心のポストバック前のデータがありませんでした。
そもそもRenderを自前で実装したコントロールはViewStateで状態復元をすることは出来ないということなのでしょうか

todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2005-08-08 18:43
> たつごろーさんに教えて頂いたページのサンプルをそのまま使ってみたのですが、
> ポストバックすると入力した内容が消えてしまいました、、、。

まずはサンプルを そのまま動かして みましょう。
サンプルが動くのであれば、サンプルを書き換えた部分に問題があるといえるでしょう。
最大40
常連さん
会議室デビュー日: 2004/02/06
投稿数: 41
投稿日時: 2005-08-08 18:48
自己レスです

nodera さんに教えて頂いた方法で、RegisterRequiresPostBackを行うのをOnloadからOnInitに変更したところ、正常に状態を復元できました。

有難うございました。

>todo さん

サンプルはコピー&ペーストで全く変更せずに実行したのですが、
ポストック後のデータは保持されませんでした。。
RegisterRequiresPostBackも含まれていませんし、、謎です
1

スキルアップ/キャリアアップ(JOB@IT)