5

我有一个 UserControl,包含一个 FormView,包含一个 DropDownList。FormView 绑定到数据控件。

像这样:

<asp:FormView ID="frmEdit" DataKeyNames="MetricCode" runat="server" DefaultMode="Edit" DataSourceID="llbDataSource" Cellpadding="0" >
    <EditItemTemplate>
        <asp:DropDownList ID="ParentMetricCode"  runat="server" SelectedValue='<%# Bind("ParentMetricCode") %>' />
    </EditItemTemplate>
<asp:FormView>

我正在尝试从代码隐藏中填充 DropDownList。如果这不包含在 FormView 中,我通常会在 Page_Load 事件中执行此操作。但是,这在 FormView 中不起作用,只要我尝试这样做,访问代码中的下拉列表,即:

theListcontrol = CType(formView.FindControl(listControlName), ListControl)  

...调用了FormView的数据绑定机制,当然,它试图将DropDownList绑定到底层数据源,导致**'ParentMetricCode'有一个无效的SelectedValue,因为它不存在于列表中项目。“参数名称:值 ...”错误,因为 DropDownList 尚未填充。

我尝试在 FormView 的 DataBinding() 事件中执行加载,但随后:

theListcontrol = CType(formView.FindControl(listControlName), System.Web.UI.WebControls.ListControl)

...失败,因为此时 FormView.Controls.Count = 0。

这是不可能的吗?(我不想使用辅助 ObjectDataSource 将下拉列表绑定到)

4

3 回答 3

4

直接OnDataBinding在您的DropDownList.

当您将表单视图绑定到某些数据时OnDataBindingDropDownList将会触发。此时,您可以将所需的值加载到列表中,并将选定的值也绑定到加载的列表中。

这是一个例子:

<asp:DropDownList ID="ParentMetricCode"  runat="server" OnDataBinding="ParentMetricCode_DataBinding" />

然后实现 OnDataBinding:

protected void ParentMetricCode_DataBinding(object sender, System.EventArgs e)
{            
    DropDownList ddl = (DropDownList)(sender);

    // Fill the list items however you want
    ddl.Items.Add(new ListItem("1", "1"));
    ddl.Items.Add(new ListItem("2", "2"));
    // etc...

    // Set the selected value
    ddl.SelectedValue = Eval("ParentMetricCode").ToString();
}

DataBind你的 FormView 时,一切都会开始发挥它的魔力 :)

此外,如果您DropDownList从数据库加载列表数据或您可能想要缓存它的东西,因为每个“行”数据都会导致加载列表数据。

编辑: 既然你认为这是不可能的,我写了一个快速演示应用程序来证明它是如何工作的:

在您的 aspx 文件中包括以下内容:

<asp:FormView ID="fvTest" runat="server">
    <ItemTemplate>
        <asp:DropDownList ID="ddlTest" runat="server" OnDataBinding="ddlTest_DataBinding"></asp:DropDownList>
    </ItemTemplate>
</asp:FormView>

然后在您的 .cs 文件中:

public class MockData
{
    public string ID { get; set; }
    public string Text { get; set; }
}

protected void Page_Load(object sender, EventArgs e)
{
    List<MockData> lst = new List<MockData>();
    lst.Add(new MockData() { ID = "3", Text = "Test3" });
    fvTest.DataSource = lst;
    fvTest.DataBind();
}

protected void ddlTest_DataBinding(object sender, System.EventArgs e)
{
    DropDownList ddl = (DropDownList)(sender);
    ddl.Items.Add("1");
    ddl.Items.Add("2");
    ddl.Items.Add("3");
    ddl.Items.Add("4");
    ddl.Items.Add("5");

    ddl.SelectedValue = Eval("ID").ToString();
 }

运行代码...DropDownList将加载所有值并设置为在模拟对象中设置的正确选定值。

不知道我还能做些什么来证明它更好......我认为你错过了 DataBinding 的实际工作方式。如果您尝试在关卡中执行此操作,则在实际绑定FormView之前不会生成控件。FormView当绑定发生时,您可以通过实现它的OnDataBinding事件来触发模板中的每个控件来执行某些操作。此时,绑定对象的当前迭代及其值可用,这就是您看到我的代码执行Eval("ID").

于 2010-03-12T19:38:25.113 回答
2

它使用 OnDataBound 事件而不是在创建控件之前发生的 OnDataBinding 为我工作。

<asp:DropDownList ID="ddlCountry" runat="server" DataSourceID="SqlDataSrcCountries" AutoPostBack="True" DataTextField="name" DataValueField="code" OnDataBound="ddlCountry_DataBound">
</asp:DropDownList>

代码隐藏:

Protected Sub ddlCountry_DataBound(ByVal sender As Object, ByVal e As System.EventArgs)

    Dim ddlCountry As New DropDownList
    Dim strCountry As String = String.Empty
    Dim lstItemToFind As New ListItem

    ddlCountry = FormViewUsers.FindControl("ddlCountry")
    strCountry = Eval("country")
    lstItemToFind = ddlCountry.Items.FindByValue(strCountry)

    If (Not IsNothing(lstItemToFind)) Then
        ddlCountry.SelectedValue = strCountry
    End If

End Sub

如果您在编辑以外的其他模板上使用它,您只需要验证:

    If (FormViewUsers.CurrentMode = FormViewMode.Edit) Then

    End If
于 2011-05-30T20:05:28.420 回答
1

好的,找到“一个”解决方案: 1. 从事件中
调用 DDL 填充函数。 2. 修改代码以填充 DDL,如下所示:FormView_ItemCreated

Public Overloads Shared Sub BindListControl(Of theLLBLgenEntityType As EntityBase) _   
        (ByVal formView As FormView, _
        ByVal listControlName As String, _
        ByVal theCollection As CollectionCore(Of theLLBLgenEntityType), _
        ByVal DataValueField As EntityField, _
        ByVal DataTextField As EntityField, _
        ByVal IncludeEmptyItem As Boolean)

    If formView.CurrentMode = FormViewMode.Edit Then
        Dim theListcontrol As System.Web.UI.WebControls.ListControl
        theListcontrol = CType(formView.FindControl(listControlName), System.Web.UI.WebControls.ListControl)

    For Each entity As theLLBLgenEntityType In theCollection
        theListcontrol.Items.Add(New ListItem(entity.Fields(DataTextField.Name).CurrentValue.ToString, entity.Fields(DataValueField.Name).CurrentValue.ToString))
    Next

    If IncludeEmptyItem Then 
        theListcontrol.Items.Insert(0, New ListItem("", ""))
    End If
End Sub

似乎基本上归结为,您不能在运行时以编程方式在 FormView 中执行其他“数据绑定”。

(任何人都知道为什么我的代码格式在这篇文章中都搞砸了??)

更新

该解决方案引发了另一批与插入新项目相关的问题。经过一番折腾,我终于找到了解决办法。在这一点上,我基本上建议要么完全避免使用 FormView 控件,要么绝对避免以编程方式更改绑定控件。希望对每个 DropDownList 使用单独的数据控件可能会更好,但这也可能是一厢情愿的想法。

于 2010-03-12T20:45:21.460 回答