動的データの外部キーフィールド用の新しいボタン
-
06-07-2019 - |
質問
ASP.NET 動的データのスキャフォールド ページで、エンティティに外部キー フィールドがあり、求める値が主キー テーブルにない場合、つまり、がドロップダウンにない場合は、エンティティへの編集を放棄し、必要な外部キー値をテーブルに追加して、元のエンティティに戻る必要があります。
外部キー フィールド テンプレートに「新規」リンク/ボタンを追加すると、新しいウィンドウが開き (パネルが表示され)、そこで求めた値を追加してドロップダウンを更新できるようにするにはどうすればよいでしょうか?
解決
つまり、Django 管理 UI のような意味です ;)。現在その機能を実装しようとしています。機能するようになったら、ここにコードを投稿します。
編集:
OK、これで動作するようになりました。完全な Django スタイルです...説明すると少し長くなりますが、実際は簡単です。
作成するファイル:
優れたポップアップ ページを作成するための admin_popup.master (ヘッダーなしで admin.master をコピーします)。
admin_popup.master をマスターとする Popup_Insert.aspx。(Insert.aspx をコピーします)
修正
admin.master.cs へ:これを追加:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "refresh_fks", @"
var fk_dropdown_id;
function refresh() {
__doPostBack(fk_dropdown_id,'refresh');
};", true);
}
admin_popup.master で、これらの属性を body タグに追加します (ポップアップのサイズを変更するために使用されます)。
<body style="display: inline-block;" onload="javascript:resizeWindow();">
admin_popup.master.cs 内
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "refresh_fks", @"
var fk_dropdown_id;
function refresh() {
__doPostBack(fk_dropdown_id,'refresh');
};", true);
System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "resize_window", @"function resizeWindow() {
window.resizeTo(document.body.clientWidth + 20, document.body.clientHeight + 40);
window.innerHeight = document.body.clientHeight + 5;
window.innerWidth = document.body.clientWidth;
}", true);
System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "update_parent", @"function updateParent() {
window.opener.refresh();
}", true);
}
Popup_Insert.aspx.cs で、次の 2 つの関数を置き換えます。
protected void DetailsView1_ItemCommand(object sender, DetailsViewCommandEventArgs e) {
if (e.CommandName == DataControlCommands.CancelCommandName)
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Close_Window", "self.close();", true);
}
protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e) {
if (e.Exception == null || e.ExceptionHandled) {
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Close_Window", "window.opener.refresh(); self.close();", true);
}
}
ForeignKey_Edit.ascx で LinkButton (ID=LinkButton1) を追加し、ForeignKey_Edit.ascx.cs でその関数を置き換えます。
protected void Page_Load(object sender, EventArgs e) {
if (DropDownList1.Items.Count == 0)
{
if (!Column.IsRequired) {
DropDownList1.Items.Add(new ListItem("[Not Set]", ""));
}
PopulateListControl(DropDownList1);
LinkButton1.OnClientClick = @"javascript:fk_dropdown_id = '{0}';window.open('{1}', '{2}', config='{3}');return false;".FormatWith(
DropDownList1.ClientID,
ForeignKeyColumn.ParentTable.GetPopupActionPath(PageAction.Insert),
"fk_popup_" + ForeignKeyColumn.ParentTable.Name, "height=400,width=600,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,directories=no,status=no");
}
if (Request["__eventargument"] == "refresh")
{
DropDownList1.Items.Clear();
if (!Column.IsRequired)
{
DropDownList1.Items.Add(new ListItem("[Not Set]", ""));
}
PopulateListControl(DropDownList1);
DropDownList1.SelectedIndex = DropDownList1.Items.Count - 1;
}
}
最後に、私が使用する 2 つの拡張関数です (好きな場所に配置してください)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Web.DynamicData;
using System.Web.UI;
public static class Utils
{
[DebuggerStepThrough]
public static string FormatWith(this string s, params object[] args)
{
return string.Format(s, args);
}
public static string GetPopupActionPath(this MetaTable mt, string action)
{
return new Control().ResolveUrl("~/{0}/popup_{1}.aspx".FormatWith(mt.Name, action));
}
}
global.asax で、次の行を変更して新しいルートを登録します。
Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert|popup_Insert" }),
わかりました、何も忘れていないといいのですが...確かに改善される可能性はありますが、機能します。わかりました。ASP.NET 動的データがさらに優れたものになるため、これが便利だと感じる人もいると思います ;)。ここでは多対多の関係を見ていきます。
他のヒント
注意:VB.net ユーザー
もしあなたが私と同じように、Dynamic Data がどれほど複雑で混乱しているかについて口を閉ざしているなら、これはあなたのためのものです。私は DD の基本を理解するだけで 100 時間以上かかりました (たとえ私が他のデータベース プログラミング技術に精通していたとしても)。
私たちにとって、ギヨームの解決策はノートンの解決策よりもはるかに簡単です。Naughton のコードを翻訳するのに 15 時間以上費やした後、Guillaume のコードを翻訳しようとしましたが、作業に移るまでにかかった時間はわずか 2 時間でした。こちらも同じ順番です。(注記:cs 拡張子はもちろん vb 拡張子に変換されます)
admin.master.cs の指示は無視してください。
admin_popup.master コードを実行します。まだ VS 2008 以前を使用している場合は、インライン ブロック引用符で CSS エラーが発生します。エラーを無視してください。
マスター ファイル OnInit サブ:
Protected Overrides Sub OnInit(ByVal e As EventArgs) MyBase.OnInit(e) System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType, "refresh_fks", " var fk_dropdown_id; function refresh() { __doPostBack(fk_dropdown_id,'refresh'); };", True) System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType, "resize_window", "function resizeWindow() { window.resizeTo(document.body.clientWidth + 120, document.body.clientHeight + 120); window.innerHeight = document.body.clientHeight + 5; window.innerWidth = document.body.clientWidth; }", True) System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType, "update_parent", "function updateParent() { window.opener.location.reload(true); }", True)
エンドサブ
カスタム ページの下の (popup_Insert.aspx.vb) 内のイベントを次のように置き換えます。
Protected Sub DetailsView1_ItemCommand(ByVal sender As Object, ByVal e As DetailsViewCommandEventArgs) If e.CommandName = DataControlCommands.CancelCommandName Then System.Web.UI.ScriptManager.RegisterClientScriptBlock(Me, Me.GetType, "Close_Window", "self.close();", True) End If
subプロテクションのsub datureview1_iteminserted(byval sender as object、byval e as dature a datearsertedeventargs)の場合、E.exceptionがolelse e.exceptionhandled then system.web.ui.scriptmanager.registerclientscriptblock(me、me.gettype、 "close_window"、 "、"、 " opener.location.reload(true);self.close(); "、true)end end sub
ForeignKey_Edit からカスタム FieldTemplate を作成し、ForeignLinkKey_Edit.ascx という名前を付けます。彼が述べたように、dropdownlist1 コントロールの後にスペース ( ) を 2 つ追加し、asp:LinkButton を作成します。「__を追加」などのテキストを入力します。Page Load 関数を次のように置き換えます。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If DropDownList1.Items.Count = 0 Then If Not Column.IsRequired Then DropDownList1.Items.Add(New ListItem("[Not Set]", "")) End If PopulateListControl(DropDownList1) LinkButton1.OnClientClick = "javascript:fk_dropdown_id = '" & DropDownList1.ClientID & _
"'; window.open('"&foreignkeycolumn.parenttable.getActionPath( "INSERT")。 .name& "'、config ='"&_ "height = 400、width = 400、toolbar = no、menubar = no、no、no、resizable = no、location = no、directories = no、no = no"& "'); false;" if request( "__ eventArgument")= "refresh" not dropdownlist1.items.clear()column.isRequired then dropdownlist1.items.add(new listitem( [not set]、 ""))populateListcontrololの場合は終了します。 (dropdownlist1)dropdownlist1.selectedindex = dropdownlist1.items.count -1 end if end sub
拡張機能は無視してください。
提案された更新されたルーティングを実行します。注記:カスタム ルートを使用している場合は、ルーティングが正しくなるまでいじる必要があります。
または、ここで2つのサーバーコントロールとブログ投稿を作成しました。 ダイナミックデータのポップアップ挿入コントロールこれはほとんど同じですが、ポップアップウィンドウからメインウィンドウとポップアップボタンに値bakを渡すサーバーコントロールのポップアップ機能をカプセル化します。
VS2010 RCのダイナミックデータの新機能はありますか?このRCの下での動的データの単純なマスター/ディテールのために、これらのようなハッキングに頼らなければなりませんか?
VS2010 RCでのDDに関するいくつかのブログ投稿を楽しみにしています...