2015-05-01 3 views
0

Я только начал использовать PostSharp, в настоящее время для функциональности Undo/Redo, которая предоставляется, но, вероятно, для гораздо большего будущего.Вложенные операции отмены/повтора с PostSharp

Мне интересно, есть ли способ реализовать вложенный набор операций в нашем приложении.

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

То, что я хочу, это разрешить пользователю выйти из редактора и теперь иметь одну операцию в стеке «Отменить» - «Отменить изменения сообщений» или что-то подобное. Это включает в себя принятие всех индивидуальных изменений и объединение их в одну операцию при отклонении редактора. В настоящее время я изучаю методы OperationScope, но я не уверен, что иду в правильном направлении. Когда в пределах области действия операции не добавляются сразу к стеку отмены, они добавляются только тогда, когда область действия закрыта, что не совсем то, что я хочу.

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

private void btnShowEditor_Click(object sender, EventArgs e) 
    { 
     // Nothing on the undo stack at this point 
     LaunchEditorWindow(); 

     // I would like one composite operation at this point that can undo all of the changes made within LaunchEditorWindow 
    } 

    // Imagine this code is inside an editor window and the changes are being done by the user 
    private void LaunchEditorWindow() 
    { 
     _network.Messages.Add(new Message() { Name = "Message 1", BitLength = 1 }); 

     // I would expect there to be three undo operations available here 
     System.Diagnostics.Debug.WriteLine(RecordingServices.DefaultRecorder.UndoOperations.Count); 

     _network.Messages.Add(new Message() { Name = "Message 2", BitLength = 2 }); 

     // 6 operations now 
     _network.Messages.Add(new Message() { Name = "Message 3", BitLength = 3 }); 

     // etc etc 
     _network.Messages.Add(new Message() { Name = "Message 4", BitLength = 4 }); 

     System.Diagnostics.Debug.WriteLine(RecordingServices.DefaultRecorder.UndoOperations.Count); 
    } 

ответ

1

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

OperationScope не позволит вам раскрывать иерархическую структуру для ваших пользователей. Области могут быть иерархическими, но операции автоматически «сплющиваются», т. Е. Новая область не всегда приводит к новой операции (родительская операция повторно используется, если она существует, если новая область не является атомарной).

Вы можете исследовать точки восстановления (см. http://doc.postsharp.net/m_postsharp_patterns_recording_recorder_addrestorepoint_762235a2).

Похоже, что вы хотите объединить все операции из точки восстановления в текущую точку в новую операцию с заданным именем. Текущий API не позволяет это делать. Я добавил запрос функции http://postsharp.uservoice.com/forums/4949-feature-requests/suggestions/7776894-undo-redo-api-to-merge-operations, и я призываю вас проголосовать за него.

Обратите внимание, что вы можете реализовать эту функцию самостоятельно, создав пользовательскую «модель представления» в верхней части Recorder.UndoOperations, которая отображает операции с использованием уровня агрегирования, который имеет для вас значение. Это разумные варианты, потому что это даст вам полный контроль над взглядом пользователя на систему отмены/повтора, которая в основном вы хотите. Однако это означает, что вам нужно будет создать свои собственные кнопки отмены/повтора.

+0

Благодарим вас за ответ Гаэль, вскоре после публикации моего вопроса я понял, что я должен смотреть на механизмы точки восстановления и что я, вероятно, в конечном итоге использую эти точки восстановления в качестве маркера, чтобы мы могли представить пользователю один раз, когда они закрыли наш редактор. Я проголосовал за проблему UseVoice, которую вы любезно создали, пальцы скрещены, что-то из этого вышло! Я ожидал, что это будет относительно общим требованием. Я добавлю свои мысли о реализации фактической (идеальной) функции в билет UserVoice. – Anthony

Смежные вопросы