Новая кнопка для полей внешнего ключа в динамических данных
-
06-07-2019 - |
Вопрос
На странице с каркасом в ASP.NET Динамические данные, если объект имеет поле внешнего ключа, а искомое значение отсутствует в таблице первичных ключей, т.е.если его нет в раскрывающемся списке, вы должны отказаться от своих правок в объекте, добавить искомое значение внешнего ключа в его таблицу и вернуться к исходному объекту.
Как я мог бы добавить "Новую" ссылку / кнопку в шаблон поля внешнего ключа, которая открыла бы новое окно (сделала бы панель видимой), куда вы можете добавить искомое значение, а затем обновить выпадающий список?
Решение
Вы имеете в виду, как в пользовательском интерфейсе администратора django ;).В настоящее время я пытаюсь реализовать эту функцию, я опубликую код здесь, если у меня получится, чтобы он заработал.
Редактировать:
Хорошо, у меня получилось, завершите стиль django...Это довольно долго объяснять, но на самом деле просто.
Файлы для создания:
A admin_popup.master, чтобы иметь красивую всплывающую страницу (скопируйте admin.master без заголовка).
popup_Insert.aspx с admin_popup.master в качестве ведущего.(скопируйте файл Insert.aspx)
Изменения
Вашему администратору.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 (он используется для изменения размера poup).
<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 замените эти две функции:
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;
}
}
И, наконец, две функции расширения, которые я использую (поместите их туда, где вы хотите):
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
Если вы были похожи на меня и недовольны тем, насколько запутанными и беспорядочными являются динамические данные, это для ВАС! Мне потребовалось более 100 часов, чтобы понять основы DD (хотя я очень разбираюсь в других технике по программированию баз данных).
Решение Гийома для нас намного проще, чем Нотона. После 15 с лишним часов попыток перевести Нотона, я попытался перевести код Гийома, и мне потребовалось всего 2 часа, чтобы добраться до работы. Здесь это в том же порядке. (Примечание: расширения cs, конечно, переводятся в расширения vb)
<Ол>Игнорировать указания admin.master.cs.
Сделайте код admin_popup.master. Если вы все еще в VS 2008 или старше, вы получите ошибку CSS в цитате встроенного блока. Игнорировать ошибку.
MASTER FILE OnInit Sub:
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)
End Sub
Замените события в (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
End Sub Защищенный Sub DetailsView1_ItemInserted (ByVal отправитель как объект, ByVal e как DetailsViewInsertedEventArgs) Если e.Exception ничто, или eEExceptionHandled System.Web.UI.ScriptManager.RegisterClientScriptBlock (Me, Me.GetType, " Close_Window " ;, " window.opener.location.reload (true); self.close (); " ;, True) End If End Sub
Создайте пользовательский шаблон FieldTemplate из ForeignKey_Edit и назовите его ForeignLinkKey_Edit.ascx. После элемента управления dropdownlist1 добавьте два пробела (& nbsp;), а затем создайте asp: LinkButton, как он сказал. Поместите текст как " Добавить __ " или что-то типа того. Замените функцию загрузки страницы следующим:
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 (' " & amp; ForeignKeyColumn.ParentTable.GetActionPath (" Insert "). Replace (" Insert.aspx " ;, " popup_Insert.aspx ") & amp; _ " ',' " & Амп; & Quot; fk_popup_ & Quot; & Амп; ForeignKeyColumn.ParentTable.Name & amp; " ', config =' " & Амп; _ & Quot; высота = 400, ширина = 400, панель инструментов = нет, строка меню = нет, полосы прокрутки = нет, изменяемыми = нет, расположение = нет, каталоги = нет, статус = нет & Quot; & Амп; " '); вернуть false; " End If Если запрос (" __ eventargument ") = " refresh " затем DropDownList1.Items.Clear () Если не столбец. Требуется то DropDownList1.Items.Add (Новый ListItem (" [Не установлено] " ;, " "))) End If PopulateListControl (DropDownList1) DropDownList1.SelectedIndex = DropDownList1.Items.Count - 1 End If End Sub
Игнорировать функции расширений.
Сделайте предложенную обновленную маршрутизацию. Примечание. Если вы используете пользовательские маршруты, вам придется с ними повозиться, пока маршрутизация не будет правильной.
Или я только что создал два серверных элемента управления и запись в блоге здесь: Элемент управления вставкой всплывающих окон для динамических данных это делает почти то же самое, но инкапсулирует функциональность всплывающих окон в элементах управления сервером, передавая значение bak из всплывающих окон в главные окна и всплывающую кнопку.
Какие-нибудь новые функции в динамических данных в VS2010 RC? Придется ли нам прибегать к таким хаки для простых основных данных в динамических данных под этим RC?
Будем рады некоторым сообщениям в блоге о DD под RC2010 RC ...