Массовое обновление явной привязки в WPF

#c# #wpf #data-binding

#c# #wpf #привязка данных

Вопрос:

Я пишу приложение WPF и в нем несколько моделей. Каждая модель имеет элемент управления редактором, с помощью которого я могу просматривать и редактировать объекты этой модели.

Например:

         <Label Content="{Binding ID}" />

        <TextBox Text="{Binding FirstName}" />
        <TextBox Text="{Binding LastName}" />
        <TextBox Text="{Binding Department}" />
        <TextBox Text="{Binding TelephoneNumber}" />
        <xceed:ByteUpDown Value="{Binding AccessLevel1}" Maximum="64" />
        <xceed:ByteUpDown Value="{Binding AccessLevel2}" Maximum="64"/>
        <xceed:IntegerUpDown Value="{Binding PIN}" />
        <xceed:IntegerUpDown Value="{Binding KeyCode}" />
        <xceed:IntegerUpDown Value="{Binding UserLimit}" />
  

Всякий раз, когда я изменяю значение, оно обновляется в модели, и это здорово; но я также хочу добавить поведение сохранения / отмены:

При «Сохранить», и только после этого, данные будут скопированы в модель, а при «Отменить» данные будут перезагружены из модели.

Я не уверен, как это сделать.

Один из способов, о котором я подумал, — пометить все привязки w / UpdateSourceTrigger=Explicit , но для обновления исходного кода требуется большое количество шаблонного кода, и это может стать немного громоздким, поскольку некоторые модели имеют более 20 редактируемых свойств.

Есть ли лучший способ сделать это?

Редактировать: я подумал, что, возможно, кто-то, читающий это в будущем, хотел бы иметь решение, которое я использовал.

Учитывая class Key :

 class Key
{
    private KeyViewModel viewModel;

    public KeyViewModel ViewModel
    {
        get
        {
            if (viewModel == null)
                viewModel = new KeyViewModel(this);
            return viewModel;
        }
    }
    // -=-=- Lots amp; lots of properties -=-=- //
}

public class KeyViewModel : Key
{
    public Key Parent { get; set; }
    public KeyViewModel(Key parent)
    {
        Parent = parent;
        CopyFromModel();
    }
    public void CopyToModel()
    {
        Type t = typeof(Key);
        var props = t.GetProperties();
        foreach (var p in props)
        {                
            if (p.CanWrite)
                p.SetValue(Parent, p.GetValue(this));
        }
    }
    public void CopyFromModel()
    {
        Type t = typeof(Key);
        var props = t.GetProperties();
        foreach (var p in props)
        {
            if (p.CanWrite)
                p.SetValue(this, p.GetValue(Parent));
        }
    }
}
  

Комментарии:

1. Создайте объект-оболочку вокруг вашей модели и свяжите с ним. После нажатия кнопки Сохранить скопируйте все значения в модель из этого объекта-оболочки.

Ответ №1:

Как насчет того, чтобы не обновлять Model (сохранять значения на ViewModel уровне) до «Сохранено» и перезагружать значения из Model ViewModel «Отменено»?

Комментарии:

1. Не могли бы вы уточнить? Должен ли я создать еще один уровень абстракции между моделью и представлением?

2. Да, но если вы хотите сохранить его View / Model , вы также можете иметь «копию» модели, к которой вы привязываетесь, на Model уровне загрузки / сохранения из оригинала. Но наличие Model / View / ViewModel layers ( MVVM ) и выполнение такого поведения приложения в VM , безусловно, является лучшим выбором.

3. Спасибо, я напишу ViewModel и буду его использовать.

Ответ №2:

Еще одним способом достижения этой цели может быть сохранение и предоставление временной модели на вашей виртуальной машине и привязка пользовательского интерфейса к ней.

Как только пользователь нажмет Сохранить, обновите фактическую модель вашими временными значениями модели. Если пользователь нажмет кнопку Отмена, просто очистите временные значения модели. Продолжайте обновлять временную модель фактическими выбранными значениями модели. Таким образом, ваша временная модель будет действовать как промежуточный контейнер значений.

Комментарии:

1. думаю, @franssu предложил это вам в своих комментариях