我有一个Person类,其中包含诸如FirstName,LastName,EmployeeID等属性。所有上述属性都只是单个字符串。 Person类还有一些属性是我定义的其他对象的列表。 例如,Person对象有一个名为“PhoneNumbers”的属性,它是List<PersonPhoneNumbers>
。 PersonPhoneNumbers是一个包含基本属性的类,例如Number,Extension,Type。GridView.Datasource为空 - 寻找替代解决方案
现在,我有一个Web窗体来编辑Person对象。它包含所有基本人员属性的文本字段以及用于显示类型为List<T>
类型的属性的网格视图。
我绑定了代码背后的所有控件。我在声明性的aspx页面中没有数据源控件。
在后面的代码中,我有一个名为“_myPerson”的私有变量,类型为“Person”。当页面第一次加载时,它会检查QueryString是否有“ID”值,如果存在,它将使用该值实例化“_myPerson”对象。该过程将转到数据库并获取数据并填充“_myPerson”对象的所有属性。
然后我调用一个名为“LoadFormControlsFromPerson()”的方法来设置所有表单字段的值。 这里是方法:
/// <summary>
/// Fills the form controls from the data in the Person object.
/// </summary>
private void LoadFormControlsFromPerson()
{
// Fill Data
txtFirstName.Text = myPerson.FirstName;
txtMiddleName.Text = myPerson.MiddleName;
txtLastName.Text = myPerson.LastName;
txtEmployeeID.Text = myPerson.EmployeeID;
if (myPerson.SOMRelationshipType.Id != CommonBase.Int_NullValue)
{
ddlSOMRelationshipType.SelectedValue = myPerson.SOMRelationshipType.Id.ToString();
}
else
{
ddlSOMRelationshipType.SelectedIndex = 0;
}
cbDisabledFlg.Checked = myPerson.DisabledFlg;
if (!myPerson.IsNew)
{
lblSidePanelID.Text = myPerson.Id.ToString();
lblSidePanelName.Text = myPerson.FirstName + " " + myPerson.LastName;
}
gvPhoneNumbers.DataSource = myPerson.PhoneNumbers;
gvPhoneNumbers.DataBind();
SetFormControlsUsability();
}
到目前为止,这么好。一切都显示出来,包括我的电话号码(gvPhoneNumbers)网格。 GridView的定义如下:
<asp:GridView ID="gvPhoneNumbers" runat="server"
AutoGenerateColumns="false" DataKeyNames="ID" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btnEditPhoneNumber" runat="server" Text="Edit" CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Number" HeaderText="Number" />
<asp:BoundField DataField="Extension" HeaderText="Extension" />
<asp:BoundField DataField="CountryCode" HeaderText="CountryCode" />
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label ID="lblPersonPhoneNumberRelationshipType" runat="server" Text='<%# Bind("RelationshipType.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="PrimaryFLG" HeaderText="Primary" />
</Columns>
</asp:GridView>
当我“保存”,另一种方法称为“LoadPersonFromFormControls”填充具有从窗体控制数据Person对象的用户点击。这是该方法:
/// <summary>
/// Updates a passed Person object with data from the form controls.
/// </summary>
private void LoadPersonFromFormControls(Person passedPerson)
{
passedPerson.FirstName = txtFirstName.Text.Trim();
passedPerson.MiddleName = txtMiddleName.Text.Trim();
passedPerson.LastName = txtLastName.Text.Trim();
passedPerson.EmployeeID = txtEmployeeID.Text.Trim();
passedPerson.SOMRelationshipType = LookupCodeManager.GetItem(int.Parse(ddlSOMRelationshipType.SelectedValue));
passedPerson.DisabledFlg = cbDisabledFlg.Checked;
passedPerson.PhoneNumbers = (EquatableList<PersonPhoneNumber>)gvPhoneNumbers.DataSource;
}
问题是,“gvPhoneNumbers.DataSource”回发后为空。在一些在线阅读之后,我的理解是Gridview不会自动“缓存”它的数据集,并且在回发后引用它的能力是不可能的,除非数据是由开发人员在会话或视图状态或某些机制中有意保存/缓存的那。
现在,我知道如果我在aspx页面中声明创建objectdatasource,gridview会记住它的数据。我之所以没有这么做是因为我不想两次获取数据;一次在代码背后的人物对象第一次实例化和第二次当objectdatasource被解雇时。
因此,我现在正考虑只在aspx页面中移动到objectdatasource,而不是在代码隐藏中设置值。我想我会为整个Person对象创建一个对象数据源,然后将formview绑定到它。 formview内部是我的gvPhoneNumber gridview,它必须绑定到formview数据源中的“子值”之一。
是否有可能将formview中的gridview绑定到formview的数据源的数据子集?如果是这样,那么声明如何定义?
另外,你认为走这条路是值得的吗?有没有人有解决这个问题的其他建议?我不想在每次页面加载时两次检索相同的数据。
嗯,我试图在回发之后遍历Gridview的每一行,并从中创建数据集,但Gridview.Rows在回发后总是空的。我确信我已经查看了所有内容,但仍然没有运气。最后,我最终将Person.PhoneNumbers列表保存在我的应用程序缓存中,并在回发后更新它,然后重新绑定gridview。似乎工作到目前为止。并没有声明数据源! – 2009-12-10 16:35:54