WebパーツコントロールにGridViewとDetailsViewを持つコードを継承しました。
DetailsViewは、TypeAとTypeBなどの2種類のオブジェクトを作成できます。
GridViewをオブジェクトタイプでフィルタリングするドロップダウンリストがあり、DetailsViewには自動的に生成された[挿入]ボタンがあります。
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="True"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
私は尋ねられました:
- GridViewのフィルターを削除します。と
- 新規ボタン/リンクを2つに分割して、各タイプのオブジェクトを作成するための個別のボタンがあるようにします。
フィルタを削除するということは、作成しているオブジェクトの種類を追跡するための別の方法が必要であることを意味します。上記を次のように変更して、新しいリンクを分割しました。
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="False"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
と追加
<FooterTemplate>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeA" CommandName="New" CommandArgument="TypeA" CssClass="buttonlink">New Type A</asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeB" CommandName="New" CommandArgument="TypeB" CssClass="buttonlink">New Type B</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</FooterTemplate>
まだフィルターを削除していないので、Newコマンドを使用しているので、変更は現在以前と同じように機能します。私ができることを望んでいたのは、なんらかの方法でNewイベントをキャプチャして、CommandArgument値を非表示フィールドに配置できるようにすることです。これにより、DetailsViewは、作成するオブジェクトのタイプを判別し、フィールドを表示/非表示にします。コード内のすべてのイベントハンドラーにブレークポイントを設定すると、最初にブレークするのはOnDetailsViewModeChangingであり、これはCommandArgumentにアクセスできません。
OnItemCommand(接続されている場合)は、DetailsView内のいずれかのボタンが押されたときにトリガーされ、CommandArgumentにアクセスできますが、このメソッド内で、次の場合に発生する一連のイベントを模倣するために正確に何を行う必要があるかわかりません。自動生成されたボタンを使用します。
CommandArgumentを取得してOnItemCommandイベントハンドラーでキャプチャするための唯一のオプションですか、それともNewコマンドでトリガーされる他のイベントがありますか?
Newコマンドがトリガーされたときに発生する一連のイベントについて誰かに説明してもらえますか?
モードが挿入に変わることをどこかで読みましたが、他に何をするのかわかりません。「挿入」リンクがクリックされるまで、OnItemInsertingメソッドは呼び出されないと思います。
どんな助けでもありがたいです!!
編集:
DetailsViewイベントでこのリンクを見つけましたが、質問に答えていません。 http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview_events.aspx
編集:
私は以下を追加しようとしました:
ascxで:
<asp:DetailsView ID="myDetailsView"
...
OnItemCommand="OnItemCommand"
...
runat="server">
...
<asp:TemplateField HeaderText="Object Type" HeaderStyle-CssClass="columnHeader">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hidObjectType" Value=""/>
<asp:Label runat="server" ID="lblObjectType"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
コードビハインド:
protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName.Equals("New"))
{
var objectType = e.CommandArgument.ToString();
HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
Label typeLabel = this.myDetailsView.FindControl("lblObjectType") as Label;
if (typeLabel != null)
{
typeLabel.Text = objectType;
}
}
}
this.myDetailsView.ChangeMode(DetailsViewMode.Insert);
OnDetailsViewModeChangingイベントハンドラーが引き続きトリガーされるため、このメソッドでモード()を設定する必要がないことがわかりました。これにより、コントロールが検出され、それらの値が正しく設定されます。OnDetailsViewModeChangingで値を再度確認すると、それらの値はまだ設定されていますが、このメソッドのロジックの一部として、
this.myDetailsView.DataBind()
これによりポストバックが発生し、この時点で値が失われます。追加してみました
EnableViewState="True"
しかし、これは何の違いもありませんでした。this.EnsureChildControls()
ページのライフサイクル(http://spazzarama.files.wordpress.com/2009/02/aspnet_page-control-life-cycle.pdf)を確認しましたが、おそらく役立つと思いましたが、違いはありませんでした。
別の方法は、セッションに値を保存することですが、私はむしろ保存しません。