【问题标题】:Web Forms Model Binding: How to omit binding for not visible control?Web 窗体模型绑定:如何省略不可见控件的绑定?
【发布时间】:2015-10-29 06:03:27
【问题描述】:

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

我非常喜欢(希望现在很有名)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>

如您所见,使用“更多数据绑定控件”的包装内面板的可见性存在一个条件。只有当条件为真并且它们是可见的时,它们才应该绑定。否则它们不应该绑定也不改变值。

更新的工作方式类似于 Scott 的帖子(简化,在 xxPage.cs 中),它是 Type Element 的通用基类:

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 页面,它们各自的代码在后面。根据用户应该成功编辑的字段,我首先调用相应的页面。

但是,这并不能解决根本问题,即条件数据绑定。

【问题讨论】:

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


    【解决方案1】:

    这更像是一种算法,而不是编码解决方案。

    我喜欢使用一个单独的类,比如 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.
    }
    

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

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

    MyBindingMethodAll(){
        // Update all controls.
    
    }
    
    MyBindingMethodVisible(){
        // Update controls that remain visible.
    
    }
    

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

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


    编辑更新以帮助阐明解决方案

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

    类管理数据

    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 传递给方法。

    这可以更好地模块化,根据您的需要,您可以传递多个 List or a List of Objects 来传递不同的控件组合。

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

    【讨论】:

    • 谢谢。这似乎是非常动态的。虽然它看起来很复杂,并且带走了新模型绑定的简单性和美感。我希望找到一些更简单的解决方案。但是,我现在已经实施了一种解决方法,请参阅更新。
    • 请离开。我最终会接受的。您能否提供有关接收一组控件以专门处理的绑定方法的链接?我在谷歌上进行了快速搜索,但到目前为止没有找到任何进一步的信息。
    猜你喜欢
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多