Подтвердить что ты не робот

Связывание модели веб-форм: как опустить привязку для не видимого элемента управления?

Я использую новую функцию привязки модели для WebForms, с .NET Framework версии 4.5.1. Я надеюсь достичь, чтобы исключить некоторые двусторонние привязки, основанные на некоторых условиях.

Мне очень нравится (надеюсь, теперь знаменитая) серия блога в блоге Скоттом Гатри. Я реализую страницу редактирования с использованием подхода номер два из привязка модели веб-форм. Часть 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>

Как вы видите, есть условие для видимости на обернутой внутренней панели с помощью "дополнительных элементов управления привязкой". Они должны связываться только, когда conditioni истинно, и они видны. В противном случае они не должны связывать и не изменять значения.

Обновление работает, как в сообщении Скотта (упрощенное, в 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(), невидимые элементы управления обновили модель, чего я хотел избежать.

Как динамически опустить привязку данных для некоторых элементов на основе условия, даже если установка их невидимая не помогает?

UPDATE: Теперь я создаю обходное решение, которое сегодня решает проблему: я просто создал две страницы .aspx со своим соответствующим кодом. В зависимости от того, какие поля пользователь должен успешно редактировать, я вызываю соответствующую страницу в первую очередь.

Это, однако, не решает основной проблемы, которая является условной привязкой данных.

4b9b3361

Ответ 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.

}

Затем вызовите методы из MyData.cs из aspx.cs. Хитрость заключается в том, чтобы поддерживать контроль за привязкой данных в С#, и вы можете точно определить, что обновляется, где и когда.

Я рад предоставить более подробный рабочий пример, если вы можете предоставить больше кода.


Изменить обновление, чтобы помочь в уточнении решения

Используя отдельный класс для управления привязкой данных, элемент отображения может быть передан методу этого отдельного класса. Я использовал хранимые процедуры.

класс ManageData​​p >

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);

Использование этого же принципала. Не видя своего макета, я могу дать вам пример концепции.

  • если у вас есть 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.
    }

}

Из aspx.cs

public List<TextBox> FindVisibleTextBoxes(){

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

    return MyTextBoxes;

}

Передать текстовый список в метод из ManageData.

Это может быть лучше модульным, в соответствии с вашими потребностями, и вы можете передать более одного списка или список объектов, чтобы пройти через гетерогенное сочетание элементов управления.

Это всего лишь одна концепция, есть много способов обойти вещи. Надеюсь, вы сочтете это полезным, чтобы разработать больше способов решить свою дилемму.