2013-10-09 2 views
5

Я использую Avalondock 2.x для одного из моих проектов с открытым исходным кодом, если документ загрязнен, когда вы его закрываете, вы сможете отменить закрытие.MVVM способ закрыть документ с возможностью отмены

Я использую Caliburn Micro и сопрограммный, только так, как я был в состоянии решить это использовать C.M прикрепить к событию

<i:EventTrigger EventName="DocumentClosing"> 
    <cal:ActionMessage MethodName="DocumentClosing"> 
     <cal:Parameter Value="$documentcontext" /> 
     <cal:Parameter Value="$eventArgs" /> 
    </cal:ActionMessage> 
</i:EventTrigger> 

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

public IEnumerable<IResult> Coroutinify(IEnumerable<IResult> results, System.Action cancelCallback) 
{ 
    return results.Select(r => 
     { 
      if (r is CancelResult) 
       cancelCallback(); 

      return r; 
     }); 
} 

Используется как

public IEnumerable<IResult> DocumentClosing(ScriptEditorViewModel document, DocumentClosingEventArgs e) 
{ 
    return Result.Coroutinify(HandleScriptClosing(document),() => e.Cancel = true); 
} 

Это работает, но это немного неуклюжий и т.д., есть более MVVM способ закрытия документов в Avalondock с возможностью отмены?

редактировать: исходный код

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Shells/MainShellView.xaml#L29

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Shells/MainShellViewModel.cs#L110

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Result/ResultFactory.cs#L49

ответ

4

Путь я достиг этого путем связывания с CloseCommand собственности на AvalonDock LayoutItem. Когда эта привязка привязана, она отменяет поведение по умолчанию закрытия документа (кнопка «X», щелкните правой кнопкой мыши закрыть/закрыть все). Затем вы несете полную ответственность за удаление (закрытие) документа, если это необходимо.

Способ, которым я настроил это, состоял в том, чтобы иметь DocumentManagerVM, который содержит ObservableCollection of DocumentVM. Каждый DocumentVM имеет ICommand с именем RequestCloseCommand, который может закрыть документ, удалив себя из коллекции DocumentVM, которой владеет DocumentManagerVM.

В частности, в моем DocumentVM ViewModel, есть ICommand (я использую mvvmLight RelayCommand) для выполнения логики закрытия:

public RelayCommand RequestCloseCommand { get; private set; } 
void RequestClose() 
{ 
    // if you want to prevent the document closing, just return from this function 
    // otherwise, close it by removing it from the collection of DocumentVMs 
    this.DocumentManagerVM.DocumentVMs.Remove(this); 
} 

На ваш взгляд, настроить ваше связывание в LayoutItemContainerStyle или LayoutItemContainerStyleSelector.

<ad:DockingManager 
    DataContext="{Binding DocumentManagerVM}" 
    DocumentsSource="{Binding DocumentVMs}"> 

    <ad:DockingManager.LayoutItemContainerStyle> 
     <Style TargetType="{x:Type ad:LayoutItem}"> 
      <Setter Property="Title" Value="{Binding Model.Header}"/> 
      <Setter Property="CloseCommand" Value="{Binding Model.RequestCloseCommand}"/> 
     </Style> 
    </ad:DockingManager.LayoutItemContainerStyle> 

</ad:DockingManager> 
+0

Я пытался найти информацию, как использовать Caliburn Micro сопрограммная вместе с командой Свойства, но нету найти хороший способ – Anders

+0

@Anders Что делать, если ваша команда находится в DocumentManagerVM. Следующая работа не работает. Я начинаю работу с документа LayoutItemContainerStyle. {Binding DataContext.RequestCloseCommand, RelativeSource = {RelativeSource, Mode = FindAncestor, AncestorType = {x: Тип объявления: DockingManager}}} – M312V

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