WPF - AvalonDock - 关闭文档

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18359818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:28:29  来源:igfitidea点击:

WPF - AvalonDock - Closing Document

c#wpfmvvmdisposedocking

提问by Eric Ouellet

I use AvalonDock with MVVM in a WPF project.

我在 WPF 项目中使用 AvalonDock 和 MVVM。

When I hit the "X" (Close button of the tab) my document closes but stays in memory. It seems that it is only hidden. It is not removed from my Model.Documentscollection.

当我点击“X”(选项卡的关闭按钮)时,我的文档关闭但保留在内存中。看来只能隐藏了。它没有从我的Model.Documents收藏中删除。

If I add DockingManager_DocumentClosingand try to remove my document from the collection, I receive an Exception in the following method of Xceed.Wpf.AvalonDock.Layout.LayoutContentbecause parentAsContaineris null.

如果我添加DockingManager_DocumentClosing并尝试从集合中删除我的文档,我会在以下方法中收到一个异常,Xceed.Wpf.AvalonDock.Layout.LayoutContent因为parentAsContainer为空。

/// <summary>
/// Close the content
/// </summary>
/// <remarks>Please note that usually the anchorable is only hidden (not closed). By default when user click the X button it only hides the content.</remarks>
public void Close()
{
    var root = Root;
    var parentAsContainer = Parent as ILayoutContainer;
    parentAsContainer.RemoveChild(this);
    if (root != null)
        root.CollectGarbage();
    OnClosed();
}

Does anybody know how I could manage document in AvalonDock that can be removed from my Model.Documentsin order to be eventually be disposed when I hit its Closebutton?

有谁知道我如何管理 AvalonDock 中的文档,这些文档可以从我的文档中删除Model.Documents,以便在我按下它的Close按钮时最终被处理掉?

For reference: This is my XAML of the AvalonDock:

供参考:这是我的 AvalonDock 的 XAML:

<avalonDock:DockingManager
    x:Name="DockingManager" 
    DocumentsSource="{Binding DocumentItems}"  
    ActiveContent="{Binding ActiveMainWindowViewModel,
        Converter={StaticResource RestrictedClassConverter},
        ConverterParameter={x:Type multiSimAnalysis:MainWindowViewModel},
        Mode=TwoWay}"
    DocumentClosing="DockingManager_DocumentClosing"
    ActiveContentChanged="DockingManager_ActiveContentChanged">

  <avalonDock:DockingManager.LayoutItemContainerStyleSelector>
    <pane:PanesStyleSelector>
      <pane:PanesStyleSelector.MainWindowViewLcStyle>
        <Style TargetType="{x:Type avalonDock:LayoutItem}">
          <Setter Property="Title" Value="{Binding Model.Title}"/>
          <Setter Property="ToolTip" Value="{Binding Model.Title}"/>
          <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}"/>
          <Setter Property="IconSource" Value="{Binding Model.IconSource}"/>
          <Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/>
          <Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
          <Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
        </Style>
      </pane:PanesStyleSelector.MainWindowViewLcStyle>
    </pane:PanesStyleSelector>
  </avalonDock:DockingManager.LayoutItemContainerStyleSelector>

  <avalonDock:DockingManager.LayoutItemTemplateSelector>
    <multiSimAnalysis:PanesTemplateSelector>
      <multiSimAnalysis:PanesTemplateSelector.MainWindowLcTemplate>
        <DataTemplate>
          <multiSimAnalysis:MainWindowViewLc /> 
        </DataTemplate>
      </multiSimAnalysis:PanesTemplateSelector.MainWindowLcTemplate>
    </multiSimAnalysis:PanesTemplateSelector>
  </avalonDock:DockingManager.LayoutItemTemplateSelector>

  <avalonDock:DockingManager.Theme>
    <avalonDock:VS2010Theme/>
  </avalonDock:DockingManager.Theme>
  <avalonDock:LayoutRoot>
    <avalonDock:LayoutPanel Orientation="Horizontal">
      <avalonDock:LayoutAnchorablePane DockWidth="400">
        <avalonDock:LayoutAnchorable Title="Scope(s) selection" x:Name="PanelScopeSelection" IsVisible="True">
          <scopeSelection:UserControlSelectStudyScope x:Name="ToolScopeSelection"/>
        </avalonDock:LayoutAnchorable>
      </avalonDock:LayoutAnchorablePane>
      <avalonDock:LayoutDocumentPane/>
      <avalonDock:LayoutAnchorablePane DockWidth="150">
        <avalonDock:LayoutAnchorable Title="Properties" x:Name="PanelScopePropertyGrid">
          <!--<multiSimAnalysis:UserControlPropertyGrid x:Name="ToolPropertyGrid"  />-->
          <xctk:PropertyGrid x:Name="ToolPropertyGrid" SelectedObject="{Binding ActiveObject}" />
        </avalonDock:LayoutAnchorable>
      </avalonDock:LayoutAnchorablePane>
    </avalonDock:LayoutPanel>
  </avalonDock:LayoutRoot>
</avalonDock:DockingManager>

采纳答案by Eric Ouellet

I actually find an unacceptable workaround. It is really twisted.

我实际上找到了一个不可接受的解决方法。它真的很扭曲。

I only give that as reference. There should be a clean way to do it.

我只是作为参考。应该有一种干净的方法来做到这一点。

    // ************************************************************************
    private void DockingManager_DocumentClosing(object sender, Xceed.Wpf.AvalonDock.DocumentClosingEventArgs e)
    {
        e.Document.CanClose = false;

        DocumentModel documentModel = e.Document.Content as DocumentModel;
        if (documentModel != null)
        {
            Dispatcher.BeginInvoke(new Action(() => this.Model.DocumentItems.Remove(documentModel)), DispatcherPriority.Background);
        }
    }

回答by Mallory

I have found that on a LayoutDocumentor a LayoutAnchorablePane, applying both this setting works: CanClose="False"or CanFloat="False".

我发现在 aLayoutDocument或 a 上LayoutAnchorablePane,应用此设置都有效:CanClose="False"CanFloat="False"

It removes the Close button.

它删除了关闭按钮。

<avalonDock:LayoutDocument Title="Board"
                           ContentId="Board"
                           CanClose="False"
                           CanFloat="False">
</avalonDock:LayoutDocument>

回答by user3389560

Register for IsVisibleChanged.

注册 IsVisibleChanged。

void layoutFPR_Hidden(object sender, EventArgs e)
{
    LayoutAnchorable window = (LayoutAnchorable)sender;
    YourClass content = window.Content as YourClass;

    // Close the object
    content = null;
    ((LayoutAnchorable)sender).Close();

}