Web窗体模型绑定:如何省略不可见控件的绑定?

Mar*_*cel 19 c# asp.net controls webforms model-binding

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

我非常喜欢Scott Guthrie撰写的(希望现在很有名)博客文章系列.我使用Web Forms Model Binding Part 3:更新和验证(ASP.NET 4.5系列)中的第二种方法实现编辑页面

这就是我所拥有的:(简化,在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>
Run Code Online (Sandbox Code Playgroud)

如您所见,包裹的内部面板上的可见性存在"更多数据绑定控制"的条件.当条件为真时,这些应该仅绑定,并且它们是可见的.否则它们不应该绑定而不能更改值.

更新的工作方式类似于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;
}
Run Code Online (Sandbox Code Playgroud)

在这里,在调用之后TryUpdateModel(),隐形控件更新了模型,这是我想要避免的.

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

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

然而,这并没有解决潜在的问题,即条件数据绑定.

Yve*_*omb 7

这是一种算法而不是编码解决方案.

我喜欢使用一个单独的类来说MyData.cs来管理我的数据更新并通过这个类的方法传递UI元素.我喜欢存储过程,但您可以在项目中创建查询.

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

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

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

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

MyBindingMethodAll(){
    // Update all controls.

}

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

}
Run Code Online (Sandbox Code Playgroud)

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

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


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

通过使用单独的类来管理数据绑定,可以将display元素传递给此单独类的方法.我使用过存储过程.

class ManageData

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

从你aspx.cs调用ManageData类的方法.

ManageData.SelectAllCat(MyDropDownList);
Run Code Online (Sandbox Code Playgroud)

使用同样的原则.
没有看到你的布局,我只能给你一个概念例子.

  • 如果你有想要控制的TextBoxes.

TextBox1,TextBox2,TextBox3,... /

public static void AddText(List<TextBox> MyTextBoxes)
{
    for(int i=0; i<MyTextBoxes.Count();i++){
        MyTextBoxes.[i].Text = // What means you are using.
    }

}
Run Code Online (Sandbox Code Playgroud)

来自aspx.cs

public List<TextBox> FindVisibleTextBoxes(){

    List<TextBox> MyTextBoxes = new List<TextBox>();
    if(TextBox1.Visible== true){
        MyTextBoxes.Add(TextBox1);
    }

    return MyTextBoxes;

}
Run Code Online (Sandbox Code Playgroud)

将文本框列表从ManageData传递到方法.

这可以更好地模块化,根据您的需要,您可以传递多个列表或对象列表来通过异构混合控件.

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

  • 谢谢.这似乎非常有活力.它看起来非常复杂,并且带走了新模型绑定的简洁性和美感.我希望找到一些更简单的解决方案.但是,我现在已经实施了一种解决方法,请参阅更新. (2认同)