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 ?

Foi útil?

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)

  1. Ignorar as admin.master.cs direções.

  2. 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.

  3. 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

  4. 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

  5. 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

  6. Ignorar as extensões de funções.

  7. 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

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 ...

scroll top