我有一个Person类,它包含FirstName,LastName,EmployeeID等属性。所有上述属性都只是单个字符串。 Person类还有一些属性,这些属性是我定义的其他对象的列表。
例如,Person对象有一个名为“PhoneNumbers”的属性,它是List<PersonPhoneNumbers>
。 PersonPhoneNumbers是一个包含基本属性的类,如Number,Extension,Type。
现在,我有一个用于编辑Person对象的Web表单。它包含所有基本Person属性的文本字段,以及用于显示List<T>
类型属性的gridviews。
我绑定了代码中的所有控件。我在声明性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();
}
到目前为止,这么好。显示所有内容,包括我的PhoneNumbers网格(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将记住它的数据。我之所以没有这样做的原因是因为我不想两次获取数据;一旦在第一个实例化person对象时的代码中,在第二次触发objectdatasource时。
所以我现在正在考虑仅在aspx页面中移动到objectdatasource,而不是在代码隐藏中设置值。我想我会为整个Person对象创建一个对象数据源,然后将一个formview绑定到它。在formview中将是我的gvPhoneNumber网格视图,它必须绑定到formview数据源中的一个“子值”。
是否可以将formview中的gridview绑定到formview数据源的数据子集?如果是这样,如何以声明方式定义?
另外,你觉得走这条路是值得的吗?有没有人有解决这个问题的其他建议?我不想为每个页面加载两次检索相同的数据。
答案 0 :(得分:1)
当页面回发时,你可以从网格行和网格单元格中检索数据吧?然后使用它们重新创建数据集或更新数据库。因此,您需要将主键存储在数据集中。
答案 1 :(得分:0)
一些想法。
在DataBind GridView之前,你要检查是否(!PostBack),以免你在GridView中过度写入数据。
保存逻辑应位于保存按钮的OnClick事件中。不在Page_Load中(如果已经在那里)。