Novo botão para campos de chave estrangeira no Dynamic Data
-
06-07-2019 - |
Pergunta
Em uma página scaffolded em ASP.NET Dynamic Data, se a entidade tem um campo de chave estrangeira, eo valor que você procura não está na tabela de chave do primário, ou seja, não está no drop-down, você tem que abandonar suas edições para a entidade, adicione o valor de chave estrangeira para a sua mesa, e retorno à sua entidade original procurava.
Como eu poderia ir sobre como adicionar um 'New' link / botão para o modelo de campo de chave estrangeira, que iria abrir uma nova janela (fazer um painel visível) onde você pode adicionar o valor procurado, e depois atualizar o drop-down ?
Solução
Quer dizer, como no django administrador ui;). Atualmente estou tentando implementar esse recurso, eu vou postar o código aqui se eu obtê-lo para o trabalho.
EDIT:
Ok, eu tenho que trabalhar, estilo de Django completa ... É meio tempo para explicar, mas simples na verdade.
Arquivos para criar:
A admin_popup.master ter uma página agradável pop-up (copiar o admin.master sem o cabeçalho).
A popup_Insert.aspx com admin_popup.master como mestre. (Copiar o Insert.aspx)
Modificações
Para seus admin.master.cs: acrescentar o seguinte:
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);
}
Em seu admin_popup.master, adicionar esses atributos para a tag body (ele é usado para redimensionar a poup)
<body style="display: inline-block;" onload="javascript:resizeWindow();">
Em seus 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);
}
Em popup_Insert.aspx.cs, substituir essas duas funções:
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);
}
}
Em ForeignKey_Edit.ascx, adicione um LinkButton (ID = LinkButton1) e em ForeignKey_Edit.ascx.cs, substituir essa função
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;
}
}
E, finalmente, as duas funções Extentions eu uso (colocá-lo onde você quer):
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));
}
}
Em seu global.asax, registrar a nova rota, alterando a linha:
Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert|popup_Insert" }),
Ok, eu espero que eu não esqueci nada ... Ele certamente poderia ser melhorado, mas funciona. Ok espero que algumas pessoas vão fint que útil, faz ASP.NET Dynamic Data muito mais melhor;). Estou goind para dar uma olhada em muitos-para-muitos relacionamentos agora.
Outras dicas
Atenção: VB.net USUÁRIOS
Se você tem sido como eu e fumegante na boca sobre como complicado e uma confusão de dados dinâmicos é, isto é para você! Levei mais de 100 horas apenas para descobrir as noções básicas de DD (mesmo que eu sou muito versado em outros techiniques de programação de banco de dados).
A solução de Guillaume é muito mais fácil do que Naughton é para nós. Após mais de 15 horas de tentar traduzir I do Naughton tentou traduzir o código do Guillaume, que me levou apenas 2 horas para chegar ao trabalho. Aqui está na mesma ordem. (Nota: extensões cs claro traduzir para extensões VB)
-
Ignorar as admin.master.cs direções.
-
Faça o código admin_popup.master. Se você ainda está no VS 2008 ou mais, você vai ter um erro de CSS no bloco de citação em linha. Ignorar o erro.
-
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
-
Substitua os eventos em (popup_Insert.aspx.vb) sob suas páginas personalizadas com este:
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 Protegido DetailsView1_ItemInserted Sub (remetente ByVal como objecto, e ByVal como DetailsViewInsertedEventArgs) Se e.Exception há nada OrElse e.ExceptionHandled Então System.Web.UI.ScriptManager.RegisterClientScriptBlock (Me, Me.GetType, "Close_Window", "window.opener.location.reload (true); self.close ();", True) Fim se End Sub
-
Criar um FieldTemplate costume fora do ForeignKey_Edit e nomeá-la ForeignLinkKey_Edit.ascx. Depois que o controle DropDownList1, adicionar dois espaços () e, em seguida, criar o asp: LinkButton como ele declarou. Coloque texto como "Adicionar __" ou algo parecido. Substituir a função de carga de página com o seguinte:
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") Substitua ( "Insert.aspx", "popup_Insert.aspx") & _ " ''" & "Fk_popup_" & ForeignKeyColumn.ParentTable.Name & " 'config ='" & _ "Height = 400, width = 400, barra de ferramentas = não, menubar = no, scrollbars = no, redimensionável = não, local = não, diretórios = não, status = não" & "'); return false;" Fim se Se Request ( "__ eventArgument") = "refresh" Então DropDownList1.Items.Clear () Se não Column.IsRequired Então DropDownList1.Items.Add (New ListItem ( "[Not Set]", "")) Fim se PopulateListControl (DropDownList1) DropDownList1.SelectedIndex = DropDownList1.Items.Count - 1 Fim se End Sub
-
Ignorar as extensões de funções.
-
Faça o atualizado roteamento sugeriu. . Nota: Se você estiver usando rotas personalizadas, você vai ter que mexer com ele até que o encaminhamento está correto
Ou eu acabou de criar dois controles de servidor e um post aqui: um pop-up Inserir controle para Dynamic Data ??a > que faz praticamente o mesmo, mas encapsula o functionlity pop-up nos controles de servidor passando um valor bak das janelas pop-up para janelas principais e botão pop-up.
Os novos recursos do Dynamic Data no VS2010 RC? Será que ainda temos de recorrer a hacks como estes para simples Mestre-Detalhes no Dynamic Data abrigo deste RC?
Olhando para a frente a alguns posts sobre DD sob VS2010 RC ...