我有一个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将下拉列表绑定到)
答案 0 :(得分:4)
直接在OnDataBinding
上实施DropDownList
。
将formview绑定到某些数据时,OnDataBinding
的{{1}}将会触发。此时,您可以将所需的值加载到列表中,并将所选值绑定到加载的列表中。
以下是一个例子:
DropDownList
然后实现OnDataBinding:
<asp:DropDownList ID="ParentMetricCode" runat="server" OnDataBinding="ParentMetricCode_DataBinding" />
当你的FormView 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
的列表数据,则可能需要对其进行缓存,因为每个“行”数据都会导致加载列表数据。
修改强> 既然你认为我不可能写一个快速的演示应用来证明它是如何工作的:
在您的aspx文件中包含以下内容:
DropDownList
然后在.cs文件中:
<asp:FormView ID="fvTest" runat="server">
<ItemTemplate>
<asp:DropDownList ID="ddlTest" runat="server" OnDataBinding="ddlTest_DataBinding"></asp:DropDownList>
</ItemTemplate>
</asp:FormView>
运行代码...... 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();
}
将加载所有值,并设置为在模拟对象中设置的正确选定值。
我不知道还能做些什么来证明它更好......我认为你错过了DataBinding的实际工作方式。如果您尝试在DropDownList
级别执行此操作,则在FormView
实际绑定之前不会进行控制。当绑定发生时,您可以通过实现它的FormView
事件来触发模板中的每个控件来执行某些操作。此时,绑定对象及其值的当前迭代可用,您可以在此处看到我的代码执行OnDataBinding
。
答案 1 :(得分: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
答案 2 :(得分:1)
好的,找到“一个”解决方案:
1.从FormView_ItemCreated
事件中调用DDL填充函数
2.修改代码以填充DDL,如下所示:
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使用单独的数据控件可能会更好,但这也可能是一厢情愿的想法。