动态数据中外键字段的新按钮

时间:2009-10-25 22:40:07

标签: asp.net dynamic-data

在ASP.NET动态数据的脚手架页面中,如果实体具有外键字段,并且您搜索的值不在主键表中,即不在下拉列表中,则必须放弃您对实体的编辑,将搜索到的外键值添加到其表中,然后返回到原始实体。

我怎样才能在外键字段模板中添加“新建”链接/按钮,这将打开一个新窗口(使面板可见),您可以在其中添加所需的值,然后刷新下拉列表?

4 个答案:

答案 0 :(得分:3)

你的意思是在django admin ui;)。 我目前正在尝试实现该功能,如果我开始工作,我会在这里发布代码。

编辑:

好的,我完成了工作,完成了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标签(它用于调整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中,添加一个LinkBut​​ton(ID = LinkBut​​ton1)并在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动态数据更好;)。我现在去看看多对多的关系。

答案 1 :(得分:2)

ATTN:VB.net USERS

如果你像我一样喜欢疯狂的动态数据,那么这就是你的意思!我花了100多个小时来弄清楚DD的基础知识(尽管我非常精通其他数据库编程技术)。

Guillaume的解决方案比Naughton的解决方案要容易得多。经过15个多小时的尝试翻译Naughton's,我试着翻译Guillaume的代码,这个代码花了我2个小时才开始工作。这是相同的顺序。 (注意:cs扩展名当然会转换为vb扩展名)

  1. 忽略admin.master.cs指示。

  2. 执行admin_popup.master代码。如果您仍处于VS 2008或更早版本,则会在内联块引用中出现CSS错误。忽略错误。

  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. 使用以下内容替换自定义页面下的(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 受保护的子DetailsView1_ItemInserted(ByVal sender As Object,ByVal e As DetailsViewInsertedEventArgs)     如果e.Exception是Nothing OrElse e.ExceptionHandled那么         System.Web.UI.ScriptManager.RegisterClientScriptBlock(Me,Me.GetType,“Close_Window”,“window.opener.location.reload(true); self.close();”,True)     万一 End Sub

  5. 从ForeignKey_Edit创建一个自定义FieldTemplate,并将其命名为ForeignLinkKey_Edit.ascx。在dropdownlist1控件之后,添加两个空格()然后按照他的说明创建asp:LinkBut​​ton。把文字像“添加__”或类似的东西。用以下代码替换页面加载功能:

    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; _ “','”&amp; “fk_popup_”&amp; ForeignKeyColumn.ParentTable.Name&amp; “',co​​nfig ='”&amp; _ “height = 400,width = 400,toolbar = no,menubar = no,scrollbars = no,resizable = no,location = no,directories = no,status = no”&amp; “');返回false;”     万一     如果请求(“__ eventargument”)=“刷新”那么         DropDownList1.Items.Clear()         如果不是Column.IsRequired然后             DropDownList1.Items.Add(New ListItem(“[Not Set]”,“”))         万一         PopulateListControl(DropDownList1)         DropDownList1.SelectedIndex = DropDownList1.Items.Count - 1     万一 End Sub

  6. 忽略扩展功能。

  7. 建议更新路由。注意:如果您使用自定义路由,则必须修改它,直到路由正确。

答案 2 :(得分:1)

或者我刚刚在这里创建了两个服务器控件和一篇博文: A Popup Insert control for Dynamic Data几乎完全相同,但封装了服务器控件中的弹出功能,将值bak从弹出窗口传递到主窗口和弹出按钮。

答案 3 :(得分:1)

VS2010 RC中动态数据的任何新功能?在这个RC下,我们是否仍然需要使用这些黑客来获取动态数据中的简单主数据?

期待在VS2010 RC下的一些关于DD的博客文章......