Автоматическая отмена изменений в DataForm при изменении выбора - PullRequest
2 голосов
/ 07 сентября 2010

Интересно, как ты это делаешь? Предположим, у нас есть приложение MVVM CRUD, которое модифицирует дерево (например, структуру меню). У нас есть модель вида с пунктами меню и два вида: первый с TreeView, а второй с DataForm. Основные проблемы:

  1. DataForm не может справиться иерархические данные.
  2. В зависимости от выбранного пункта меню в TreeView DataForm должен отображать другой набор поля (например, для пунктов меню с детьми или без).

Я закончил со следующим. Вид модели имеет 3 поля:

  1. Items - коллекция MenuItem объекты, которые имеют свои собственная Children коллекция для построение иерархического источника данных.
  2. SelectedItem - в настоящее время выбрано MenuItem в TreeView.
  3. EditedItem - EditViewModel объект, который в основном имеет два потомки: MenuItemEditViewModel и LeafMenuItemEditViewModel. Это свойство устанавливается автоматически когда SelectedItem изменяется. это фактический тип выводится из SelectedItem.Children пустота.

TreeView связан с Items и SelectedItem. DataForm не требуется для поддержания валюты в этом случае (вместо этого текущая позиция установлена ​​TreeView), а также не отвечает за создание и удаление элементов. Вот почему я решил привязать только ее CurrentItem для просмотра модели EditedItem (ItemsSource не привязан). Его AutoCommit установлен на False (когда он True и ItemsSource не привязан, все текущие изменения элемента копируются в новый выбранный элемент, когда вы выбираете другой элемент в TreeView, что не так приятно) , DataForm поля генерируются автоматически.

Очевидно, что теперь, если мы выберем элемент в TreeView, затем внесем некоторые изменения в DataForm и попытаемся выбрать другой элемент в TreeView, мы получим известную

Невозможно изменить валюту, когда предмет имеет ошибки проверки или в настоящее время отредактировано и AutoCommit имеет значение false. Задавать ItemsSource для ICollectionView для вместо этого управляйте валютой

В этом случае я хочу, чтобы DataForm неявно отклонял все изменения. Существует обходной путь для вызова DataForm.CancelEdit() до изменения TreeView выбранного элемента (обычно это событие типа PreviewSelectionChanged или BeforeSelectionChanged). Но это не MVVM-путь, поскольку TreeView и DataForm определены в совершенно разных представлениях (читай: недопустимо).

Есть ли что-то вроде AutoCancel, которая заставляет DataForm отменять изменения при изменении CurrentItem? Может кто-нибудь из команды разработчиков может ответить? Или как бы вы справились с такой проблемой?

Ответы [ 2 ]

4 голосов
/ 29 ноября 2010

Я был удивлен, обнаружив, что Silverlight остро не хватает этой функциональности, учитывая все функциональные возможности RIA, ориентированные на бизнес. AutoCommit для меня неприемлем, потому что я хочу, чтобы пользователь явно подтверждал ожидающие изменения, а не просто фиксировал что-то в базе данных, чего он может не хотеть.

Вы можете надежно отслеживать режим редактирования DataForm, используя закрытую переменную-член и перехватывая события BeginningEdit и EditEnded в DataForm (именование несоответствие! Почему одно называется xxxEdit, а другие - Editxxx, вне меня. EditBeginning и EditEnded ??). Внутри обработчика событий для BeginningEdit установите флаг в true и установите его в false в EditEnded.

В вашем событии SelectionChanged вы можете проверить флаг. Если это правда, вы можете вызвать CancelEdit в DataForm.

private bool _editing = false;

public MainPage() {
    DataForm1.BeinningEdit += 
        new EventHandler<CancelEventArgs>(DataForm1_BeginningEdit);
    DataForm1.EditEnded += 
        new EventHandler<DataFormEditEndedEventArgs>(DataForm1_EditEnded);
}

protected void DataForm1_BeginningEdit(object sender, 
    System.ComponentModel.CancelEventArgs e) {
    _editing = true;
}

protected void DataForm1_EditEnded(object sender, 
    DataFormEditEndedEventArgs e) {
    _editing = false;
}

void TreeView1_SelectedItemChanged(object sender, 
    RoutedPropertyChangedEventArgs<object> e)
{
    if (_editing) {
        object previous = DataForm1.SelectedItem;
        object current = TreeView1.SelectedItem;

        if (MessageBox.Show("Are you sure you want to cancel the changes?", 
            "Confirm", MessageBoxbutton.OKCancel) == MessageBoxResult.OK) {
            DataForm1.CancelEdit();
        }
        else {
            TreeView1.SelectedItem = previous;
        }
    }
}
0 голосов
/ 22 октября 2010

Вы пытались установить AutoCommit на True?

...