1

我有许多类似结构的 FormView。为了避免重复标记,我创建了一个包含 FormView 的母版页,并在 FormView 中放置了一个 ContentPlaceHolder。特定的数据绑定控件——这是唯一在页面之间发生变化的东西——然后位于使用该母版页的页面上。

所以我有一个看起来像这样的母版页:

<%@ master ... %>
...
<form runat=server>
...
   <asp:formview runat="server" ... >
      <edititemtemplate>
         ... Lots of common markup ...
         <asp:contentplaceholder id='FormRows' runat='server' />
         ... Lots more common markup ...
       </edititemtemplate>
    </asp:formview>
...
</form>

以及使用该母版页的页面,如下所示:

<%@ page masterpagefile="Form.Master" ... %>
<asp:content contentplaceholderid="FormRows" runat="server" >
   ...
   <p>
     Field One: 
     <asp:textbox runat=server text='<%#Bind("Field1")%>' id='Field1' />
   </p>
   <p>
     Field Two: 
     <asp:textbox runat=server text='<%#Bind("Field2")%>' id='Field2' />
   </p>
   ...
</asp:content>

使用现有记录,FormView 可以看到数据绑定控件(Field1 等)并用正确的数据填充它们。但是在插入或更新时,它看不到它们,并且它们不包含在插入或更新中。在FormView_ItemInserting事件中,e.Values是空的;同样在FormView_ItemUpdating事件中,e.NewValues是空的。

所以:

  1. 有没有办法让母版页上的 FormView 看透 ContentPlaceholder 内的数据绑定控件?

  2. 如果做不到这一点,是否有一种直接的方法来识别数据绑定的控件,<%#Bind(...)%>以便我可以手动将它们添加到值包中?

4

5 回答 5

2

有几件事让我想到为什么这个设置不起作用,并且可能导致代码多于标记。

如果您在母版页中定义了数据源,它将不会处理来自每个页面的不同数据绑定控件,而无需向母版页添加更多逻辑以更改查询等。

所有表单视图都将耦合在一起,从而增加未来更改的复杂性

我会为每个 FormView 使用单独的页面,以减少代码的复杂性、调试和更改的能力

只是我的两分钱

于 2009-04-30T14:33:25.217 回答
0

你也许可以做这样的事情......

为您的“数据页面”定义一个接口,该接口具有返回可绑定数据源的方法签名。

public interface IFormViewChild {
   IEnumerable GetFormData();
}

然后你可以让你的“数据页面”实现那个接口......

public class ChildDataPage : Page, IDataPage {
   public IEnumerable GetFormData() {
      // code to return stuff here
   }
}

最后,在您的母版页的 Load() 事件中...

if (Page is IFormViewChild) {
   myFormViewControl.DataSource = ((IFormViewChild)Page).GetFormData();
   myFormViewControl.DataBind();
}

请记住,这都是直接输入此 Web 表单编辑器的所有伪代码。所以它可能是错误的。但它可能不是:)

于 2009-05-01T00:55:15.563 回答
0

你在哪里有服务器表单标签?可能在母版页的内容占位符中,因此您的值在提交后不会发送到服务器页面

于 2009-04-26T23:58:29.370 回答
0

我认为这将被证明是困难的,如果不可能的话;事实上,我很惊讶数据绑定完全有效!

您可能想要尝试封装 FormView 控件的不同方法。

您可以尝试将 FormView 控件放置在具有 PlaceHolder 的 .ascx 控件中,您现在拥有 ContentPlaceHolder。

然后在每个 ASPX 页面上,您可以有一个包含占位符填充符的镜像 ASCX 页面。您可以给它们相同的名称(Page1.aspx 使用 Page1.ascx)或设置像 Page1-Content.ascx 这样的命名约定,以便您的 FormView ascx 会弄清楚它的填充控件的名称,使用 Page.LoadControl()通过路径加载控件,并在初始化阶段插入该内容。

现在,您的内容控件具有能够拥有公共属性的优势,因此您可以绑定到这些公共属性,并让这些属性将数据往返于填充 .ascx 文件中的适当服务器控件。

不幸的是,它是文件的两倍(因为每个页面都需要 ASPX 和 ASCX),但与替代方案(复制所有代码)相比,它的工作量相当低

当然,您还没有告诉我们您所有的通用标记是什么,但是您的通用标记也可以进入 CommonMarkupHeader.ascx 和 CommonMarkupFooter.ascx 并包含在每个页面的唯一 FormView 中。

于 2009-05-05T04:35:11.807 回答
0

这是一个临时解决方案 - 不优雅,但它有效。在 Form.Master 的代码隐藏中,我有以下内容:

    Private Sub FormView1_ItemInserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewInsertEventArgs) Handles FormView1.ItemInserting
        ManuallyAddValues(e.Values)
    End Sub

    Private Sub FormView1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles FormView1.ItemUpdating
        ManuallyAddValues(e.NewValues)
    End Sub

    Private Sub ManuallyAddValues(ByRef Values As IOrderedDictionary)
        For Each Field As Core.Field In FormView1.DataSourceControl.IncludedFields
            If Values(Field.Name) Is Nothing Then
                Dim DataboundControl As Control = FormView1.FindControl("FormRows").FindControl(Field.Name)
                Values.Add(Field.Name, GetValue(DataboundControl))
            End If
        Next
    End Sub

这不是那么优雅,因为

  1. 我必须知道所有数据绑定控件的名称
  2. 这依赖于每个控件的 ID 与字段名匹配的假设
  3. 'GetValue' 函数(此处未包括)是一个笨拙的解决方案:它检查各种类型(文本框、下拉列表、复选框等)并从适当的属性(textbox.text、dropdownlist.selectedvalue、checkbox.txt)中获取字符串值。检查等)。

我仍然希望至少有一种方法可以了解与 '<%#Bind("Foo")%>' 语法绑定的内容并直接获取该信息。

于 2009-05-05T15:01:13.563 回答