c# - Web 窗体模型绑定(bind) : How to omit binding for not visible control?

标签 c# asp.net webforms controls model-binding

我在 .NET Framework 版本 4.5.1 中使用 WebForms 的新模型绑定(bind)功能。 我希望实现的是,根据某些条件排除一些双向绑定(bind)。

我非常喜欢(希望现在出名)blog post series, by Scott Guthrie .我使用 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>

如您所见,具有“更多数据绑定(bind)控件”的包裹内部面板的可见性有一个条件。这些应该仅在条件为真且可见时才绑定(bind)。否则它们不应该绑定(bind)并且不更改值。

更新的工作方式与 Scott 的帖子(简化后的 xxPage.cs)类似,它是类型元素的通用基类:

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() 之后,不可见控件更新了模型,这是我想要避免的。

如何根据条件动态省略某些元素的数据绑定(bind),即使将它们设置为不可见也无济于事?

更新: 我现在已经创建了一个解决方法,它解决了我今天的问题:我只是创建了两个 .aspx 页面,并在后面隐藏了各自的代码。根据用户应成功编辑的字段,我会首先调用相应的页面。

但是,这并没有解决根本问题,即条件数据绑定(bind)。

最佳答案

与其说是编码解决方案,不如说这是一种算法。

我喜欢使用一个单独的类,比如 MyData.cs 来管理我的数据更新,并通过 这个类的方法。 我就像存储过程,但您可以在您的项目中创建查询。

如果控件可见和不可见之间存在差异,我建议:

MyBindingMethod(array[] of the controls){
    // Loop through array updating data.
    // Or loop through array and call a second method to update the data.
}

您可以动态地检查控件的可见性,然后将它们添加到数组中或不添加到数组中 传递给绑定(bind)方法。

如果切换可见性的控件是常量,您可以使用两种不同的方法, 有选择地更新:

MyBindingMethodAll(){
    // Update all controls.

}

MyBindingMethodVisible(){
    // Update controls that remain visible.

}

然后从您的 aspx.cs 调用 MyData.cs 中的方法。诀窍是在 C# 中保持对数据绑定(bind)的控制,您可以准确确定更新的内容、位置和时间。

如果您能够提供更多代码,我很乐意提供更详细的工作示例。


编辑更新以帮助澄清解决方案

通过使用单独的类来管理数据绑定(bind),可以将显示元素传递给这个单独类的方法。 我使用过存储过程。

管理数据类

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 类的方法。

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通过各种不同的控制。

这只是一个概念,有很多方法可以解决问题。我希望你发现这对开发更多方法来解决你的困境很有用。

关于c# - Web 窗体模型绑定(bind) : How to omit binding for not visible control?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31849843/

相关文章:

c# - 如何将 Selectlist 转换为 Html.SelectListFor()

c# - ASP.NET Core 2.0 AzureAD 身份验证不起作用

asp.net - 使用 sql helper(Microsoft.ApplicationBlocks.Data) 时的超时问题

asp.net - 如何在 Web 应用程序中创建新 ASP.NET Web 表单的超链接

javascript - 如何使用 javascript 回发到不同的表单

c# - Windows Phone 8 滚动查看器

c# - 如何一次获取所有文件属性,包括作者、标题、mp3 标签等

c# - 如何在 asp.net 中创建模块?

asp.net - VB.NET Repeater 无数据源的简单数据绑定(bind)

asp.net - 在用户控件(ASCX)中动态设置 Gridview DataNavigateUrlFormatString