【问题标题】:WPF - AvalonDock - Closing DocumentWPF - AvalonDock - 关闭文档
【发布时间】:2023-03-16 13:47:02
【问题描述】:

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

当我点击“X”(选项卡的关闭按钮)时,我的文档将关闭但仍保留在内存中。似乎只是隐藏起来了。它不会从我的Model.Documents 收藏中删除。

如果我添加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();
}

有人知道我如何在 AvalonDock 中管理可以从我的Model.Documents 中删除的文档,以便在我点击其Close 按钮时最终被处理掉吗?

供参考:这是我的 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>

【问题讨论】:

    标签: c# wpf mvvm dispose docking


    【解决方案1】:

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

    它会移除关闭按钮。

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

    【讨论】:

      【解决方案2】:

      注册 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();
      
      }
      

      【讨论】:

        【解决方案3】:

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

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

            // ************************************************************************
            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);
                }
            }
        

        【讨论】:

        • 如果您不使用 MVVM,有没有办法解决这个问题?
        • 这是一个很长的镜头,但这个活动从来没有为我呼吁过,还有其他人有类似的经历吗?
        • @Mårten,我不再使用 AvalonDock。我使用 Actipro 对接。
        • @EricOuellet 我应该在哪里编写/覆盖这个方法?
        • @Daniel,DockingManager 上应该有一个名为“DocumentClosing”的事件,该事件应该在文档关闭之前发生。这已经3年多了……也许界面变了?我们实际上正在使用 ActiPro 对接,但您必须付费。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 2011-12-11
        • 2011-07-17
        • 2022-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多