Pregunta

En una página scaffolded en ASP.NET Dynamic Data, si la entidad tiene un campo de clave externa y el valor que busca no está en la tabla de clave primaria, es decir, no está en el menú desplegable, debe abandonar sus ediciones a la entidad, agregue el valor de la clave externa buscada a su tabla y regrese a su entidad original.

¿Cómo podría agregar un enlace / botón 'Nuevo' a la plantilla de campo de clave externa, que abriría una nueva ventana (haría visible un Panel) donde puede agregar el valor buscado y luego actualizar el menú desplegable ?

¿Fue útil?

Solución

Quieres decir como en el django admin ui;). Actualmente estoy tratando de implementar esa función, publicaré el código aquí si logro que funcione.

EDITAR:

Ok, tengo que trabajar, completar el estilo django ... Es un poco largo de explicar pero simple de hecho.

Archivos para crear:

Un admin_popup.master para tener una buena página emergente (copie el admin.master sin el encabezado).

Un popup_Insert.aspx con admin_popup.master como maestro. (copie el Insert.aspx)

Modificaciones

A su admin.master.cs: agregue esto:

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);
}

En su admin_popup.master, agregue estos atributos a la etiqueta del cuerpo (se usa para cambiar el tamaño de la poup)

<body style="display: inline-block;" onload="javascript:resizeWindow();">

En su 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);        
}

En popup_Insert.aspx.cs, reemplace estas dos funciones:

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); 
    }
}

En ForeignKey_Edit.ascx, agregue un LinkButton (ID = LinkButton1) y en ForeignKey_Edit.ascx.cs, reemplace esa función

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;
    }
}

Y finalmente las dos funciones de extensiones que uso (póngalas donde quiera):

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));
    }
}

En su global.asax, registre la nueva ruta cambiando esa línea:

Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert|popup_Insert" }),

Ok, espero no haber olvidado nada ... Ciertamente podría mejorarse, pero funciona. Ok, espero que algunas personas lo encuentren útil, hace que ASP.NET Dynamic Data sea mucho mejor;). Voy a echar un vistazo a las relaciones de muchos a muchos ahora.

Otros consejos

ATENCIÓN: USUARIOS VB.net

Si ha sido como yo y echando humo por la conmoción y la confusión de los datos dinámicos, ¡esto es para USTED! Me ha llevado más de 100 horas descubrir los conceptos básicos de DD (aunque estoy muy versado en otras técnicas de programación de bases de datos).

La solución de Guillaume es mucho más fácil que la de Naughton para nosotros. Después de más de 15 horas de tratar de traducir Naughton, intenté traducir el código de Guillaume, lo que me llevó solo 2 horas en llegar al trabajo. Aquí está en el mismo orden. (Nota: las extensiones cs, por supuesto, se traducen en extensiones vb)

  1. Ignora las instrucciones admin.master.cs.

  2. Realice el código admin_popup.master. Si todavía está en VS 2008 o anterior, obtendrá un error de CSS en la cotización de bloque en línea. Ignora el error.

  3. ARCHIVO MAESTRO 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)
    

    Fin Sub

  4. Reemplace los eventos en (popup_Insert.aspx.vb) debajo de sus páginas personalizadas con esto:

    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
    

    Fin Sub Sub DetailsView1_ItemInserted protegido (remitente ByVal como objeto, ByVal e As DetailsViewInsertedEventArgs)     Si e.Exception no es nada más que e.ExceptionHandled entonces         System.Web.UI.ScriptManager.RegisterClientScriptBlock (Me, Me.GetType, " Close_Window " ;, " window.opener.location.reload (true); self.close (); " ;, True)     Terminara si End Sub

  5. Cree una FieldTemplate personalizada fuera de ForeignKey_Edit y asígnele el nombre ForeignLinkKey_Edit.ascx. Después del control dropdownlist1, agregue dos espacios (& nbsp;) y luego cree el asp: LinkButton como él dijo. Poner texto como " Agregar __ " o algo así. Reemplace la función de carga de página con esto:

    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 "). Reemplazar (" Insert.aspx " ;, " popup_Insert.aspx ") & amp; _ " ',' " &erio; " fk_popup_ " &erio; ForeignKeyColumn.ParentTable.Name & amp; " ', config =' " &erio; _ _ " altura = 400, ancho = 400, barra de herramientas = no, barra de menú = no, barras de desplazamiento = no, redimensionable = no, ubicación = no, directorios = no, estado = no " &erio; " '); devuelve falso; "     Terminara si     Si Solicitud (" __ eventargument ") = " actualizar " Entonces         DropDownList1.Items.Clear ()         Si no es columna, entonces se requiere             DropDownList1.Items.Add (New ListItem (" [No establecido] " ;, " "))         Terminara si         PopulateListControl (DropDownList1)         DropDownList1.SelectedIndex = DropDownList1.Items.Count - 1     Terminara si End Sub

  6. Ignora las funciones de extensiones.

  7. Realice el ruteo actualizado sugerido. Nota: Si está utilizando rutas personalizadas, tendrá que manipularlas hasta que la ruta sea correcta.

O acabo de crear dos controles de servidor y una publicación de blog aquí: Un control de inserción emergente para datos dinámicos eso hace más o menos lo mismo pero encapsula la funcionalidad emergente en los controles del servidor pasando un valor bak desde las ventanas emergentes a las ventanas principales y al botón emergente.

¿Alguna característica nueva en Dynamic Data en el VS2010 RC? ¿Tendremos que recurrir a hacks como estos para obtener detalles maestros simples en datos dinámicos bajo este RC?

Esperando algunas publicaciones de blog sobre DD en VS2010 RC ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top