Web 窗体模型绑定:如何省略不可见控件的绑定?
Web Forms Model Binding: How to omit binding for not visible control?
我在 .NET Framework 4.5.1 版中使用 WebForms 的新模型绑定功能。 我希望实现的是,根据一些条件排除一些的双向绑定
我非常喜欢(希望现在出名)blog post series, by Scott Guthrie. I implement an editing page using the approach number two from Web Forms Model Binding Part 3: Updating and Validation (ASP.NET 4.5 Series)
这是我所拥有的:(简化,在 ElementEdit.aspx 中):
<asp:FormView runat="server" ID="FormViewElement" RenderOuterTable="false" DefaultMode="Edit" DataKeyNames="ElementId"
ItemType="Business.Entities.Element"
SelectMethod="GetElement"
UpdateMethod="UpdateElement">
<EditItemTemplate>
<asp:Panel runat="server" DefaultButton="ButtonSpeichern">
<fieldset>
/*some databound controls*/
<asp:Panel runat="server" Visible="<%# !Item.CurrentElementData.SomeCondition() %>">
/*more databound controls*/
</asp:Panel>
/*the submit button ("ButtonSpeichern")*/
</fieldset>
</asp:Panel>
</EditItemTemplate>
</asp:FormView>
如您所见,"more databound controls" 包裹内面板的可见性有一个条件。这些应该仅在条件为真且可见时才绑定。否则他们不应该绑定并且不更改值。
更新的工作方式类似于 Scott 的 post(简化,在 xxPage.cs 中),它是类型元素的通用基础 class:
protected virtual bool UpdateEntity(int id) {
T existing = UseCase.GetItem(id); //gets the original element
TryUpdateModel(existing); //SHOULD NOT update the invisible databound controls, but does
ValidateExistingEntity(existing);
if (ModelState.IsValid) {
UseCase.Update(existing);
return true;
}
ShowErrors(ModelState);
return false;
}
在这里,在调用TryUpdateModel()
之后,不可见控件更新了模型,这是我想要避免的。
如何根据条件动态省略某些元素的数据绑定,即使将它们设置为不可见也无济于事?
更新:
我现在已经创建了一个解决方法,它解决了我今天的问题:我只是创建了两个 .aspx 页面,并在后面隐藏了各自的代码。根据用户应成功编辑的字段,我首先调用相应的页面。
然而,这并没有解决根本问题,即条件数据绑定。
与其说是编码解决方案,不如说这是一种算法。
我喜欢使用单独的 class 说 MyData.cs 来管理我的数据更新并通过 UI 元素传递
class 的方法。
我喜欢存储过程,但您可以在项目中创建查询。
如果控件可见与不可见之间存在差异,我建议:
MyBindingMethod(array[] of the controls){
// Loop through array updating data.
// Or loop through array and call a second method to update the data.
}
您可以动态地检查控件的可见性,然后将它们添加到数组或不添加到数组
传递给绑定方法。
如果切换可见性的控件不变,您可以使用两种不同的方法,
有选择地更新:
MyBindingMethodAll(){
// Update all controls.
}
MyBindingMethodVisible(){
// Update controls that remain visible.
}
然后从您的 aspx.cs 调用 MyData.cs 中的方法。诀窍是在 C# 中保持对数据绑定的控制,您可以准确确定更新的内容、位置和时间。
如果您能够提供更多代码,我很乐意提供更详细的工作示例。
编辑更新以帮助阐明解决方案
通过使用单独的 class 来管理数据绑定,可以将显示元素传递给此单独的 class 的方法。 我用过存储过程。
class 管理数据
public static void SelectAllSomething(DropDownList list)
{
// Clear any previously bound items.
list.Items.Clear();
// SqlConnection.
SqlConnection con = new SqlConnection(conString);
// Create new command and parameterise.
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "MyStoredProcedure";
cmd.Connection = con;
try
{
// Open connection and bind data to GUI.
con.Open();
list.DataSource = cmd.ExecuteReader();
list.DataTextField = "Name";
list.DataValueField = "ID";
list.DataBind();
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
}
从您 aspx.cs 调用 ManageData class 的方法。
ManageData.SelectAllCat(MyDropDownList);
使用相同的主体。
看不到您的布局,我只能给您一个概念示例。
- 如果您有想要控制的文本框。
文本框 1、文本框 2、文本框 3、.../
public static void AddText(List<TextBox> MyTextBoxes)
{
for(int i=0; i<MyTextBoxes.Count();i++){
MyTextBoxes.[i].Text = // What means you are using.
}
}
来自aspx.cs
public List<TextBox> FindVisibleTextBoxes(){
List<TextBox> MyTextBoxes = new List<TextBox>();
if(TextBox1.Visible== true){
MyTextBoxes.Add(TextBox1);
}
return MyTextBoxes;
}
将文本框列表从 ManageData 传递到方法中。
这可以更好地模块化,根据您的需要,您可以传递多个列表 or a List of Objects 以传递不同的控件组合。
这只是一个概念,处理事情的方法有很多种。我希望你发现这对开发更多方法来解决你的困境很有用。
我在 .NET Framework 4.5.1 版中使用 WebForms 的新模型绑定功能。 我希望实现的是,根据一些条件排除一些的双向绑定
我非常喜欢(希望现在出名)blog post series, by Scott Guthrie. I implement an editing page using the approach number two from Web Forms Model Binding Part 3: Updating and Validation (ASP.NET 4.5 Series)
这是我所拥有的:(简化,在 ElementEdit.aspx 中):
<asp:FormView runat="server" ID="FormViewElement" RenderOuterTable="false" DefaultMode="Edit" DataKeyNames="ElementId"
ItemType="Business.Entities.Element"
SelectMethod="GetElement"
UpdateMethod="UpdateElement">
<EditItemTemplate>
<asp:Panel runat="server" DefaultButton="ButtonSpeichern">
<fieldset>
/*some databound controls*/
<asp:Panel runat="server" Visible="<%# !Item.CurrentElementData.SomeCondition() %>">
/*more databound controls*/
</asp:Panel>
/*the submit button ("ButtonSpeichern")*/
</fieldset>
</asp:Panel>
</EditItemTemplate>
</asp:FormView>
如您所见,"more databound controls" 包裹内面板的可见性有一个条件。这些应该仅在条件为真且可见时才绑定。否则他们不应该绑定并且不更改值。
更新的工作方式类似于 Scott 的 post(简化,在 xxPage.cs 中),它是类型元素的通用基础 class:
protected virtual bool UpdateEntity(int id) {
T existing = UseCase.GetItem(id); //gets the original element
TryUpdateModel(existing); //SHOULD NOT update the invisible databound controls, but does
ValidateExistingEntity(existing);
if (ModelState.IsValid) {
UseCase.Update(existing);
return true;
}
ShowErrors(ModelState);
return false;
}
在这里,在调用TryUpdateModel()
之后,不可见控件更新了模型,这是我想要避免的。
如何根据条件动态省略某些元素的数据绑定,即使将它们设置为不可见也无济于事?
更新: 我现在已经创建了一个解决方法,它解决了我今天的问题:我只是创建了两个 .aspx 页面,并在后面隐藏了各自的代码。根据用户应成功编辑的字段,我首先调用相应的页面。
然而,这并没有解决根本问题,即条件数据绑定。
与其说是编码解决方案,不如说这是一种算法。
我喜欢使用单独的 class 说 MyData.cs 来管理我的数据更新并通过 UI 元素传递 class 的方法。 我喜欢存储过程,但您可以在项目中创建查询。
如果控件可见与不可见之间存在差异,我建议:
MyBindingMethod(array[] of the controls){
// Loop through array updating data.
// Or loop through array and call a second method to update the data.
}
您可以动态地检查控件的可见性,然后将它们添加到数组或不添加到数组 传递给绑定方法。
如果切换可见性的控件不变,您可以使用两种不同的方法, 有选择地更新:
MyBindingMethodAll(){
// Update all controls.
}
MyBindingMethodVisible(){
// Update controls that remain visible.
}
然后从您的 aspx.cs 调用 MyData.cs 中的方法。诀窍是在 C# 中保持对数据绑定的控制,您可以准确确定更新的内容、位置和时间。
如果您能够提供更多代码,我很乐意提供更详细的工作示例。
编辑更新以帮助阐明解决方案
通过使用单独的 class 来管理数据绑定,可以将显示元素传递给此单独的 class 的方法。 我用过存储过程。
class 管理数据
public static void SelectAllSomething(DropDownList list)
{
// Clear any previously bound items.
list.Items.Clear();
// SqlConnection.
SqlConnection con = new SqlConnection(conString);
// Create new command and parameterise.
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "MyStoredProcedure";
cmd.Connection = con;
try
{
// Open connection and bind data to GUI.
con.Open();
list.DataSource = cmd.ExecuteReader();
list.DataTextField = "Name";
list.DataValueField = "ID";
list.DataBind();
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
}
从您 aspx.cs 调用 ManageData class 的方法。
ManageData.SelectAllCat(MyDropDownList);
使用相同的主体。
看不到您的布局,我只能给您一个概念示例。
- 如果您有想要控制的文本框。
文本框 1、文本框 2、文本框 3、.../
public static void AddText(List<TextBox> MyTextBoxes)
{
for(int i=0; i<MyTextBoxes.Count();i++){
MyTextBoxes.[i].Text = // What means you are using.
}
}
来自aspx.cs
public List<TextBox> FindVisibleTextBoxes(){
List<TextBox> MyTextBoxes = new List<TextBox>();
if(TextBox1.Visible== true){
MyTextBoxes.Add(TextBox1);
}
return MyTextBoxes;
}
将文本框列表从 ManageData 传递到方法中。
这可以更好地模块化,根据您的需要,您可以传递多个列表 or a List of Objects 以传递不同的控件组合。
这只是一个概念,处理事情的方法有很多种。我希望你发现这对开发更多方法来解决你的困境很有用。