2012-08-16 72 views
4

我想删除它们,因为这导致我很多问题。如果有办法解决它,我会很乐意尝试。 使用它的前几分钟我得到了3个不同的例外,我不知道如何删除这些该死的选项。删除AvalonDock码头并关闭按钮

固定和取消固定和固定,会引发InvalidOperationException,因为操作由于对象的当前状态而无效。

有时固定和取消固定将打开一个对话框,并要求我提供一个文件,我不希望发生这种情况,但它正在发生,并且会引发异常。

我不小心点击关闭按钮,我无法取回窗口。 这真的令人沮丧。我相信其他avalondock用户也遇到过这个问题。

因为我不想浪费太多时间,所以我会在这里问。 你是如何解决这些异常或删除这些按钮的?谢谢。

回答

3

我和你的问题完全一样。是否愿意从实际UI删除的图标,我只是禁止他们与事件处理

这里是我的工作:

要删除那些隐藏和自动隐藏命令:

我增加了以下处理:

CommandManager.AddPreviewExecutedHandler(this, new ExecutedRoutedEventHandler(this.ContentClosing)) 

这是ContentClosing样子:

/// <summary> 
/// Handler called when user clicked on one of the three buttons in a DockablePane 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="e"></param> 
private void ContentClosing(object sender, ExecutedRoutedEventArgs e) 
{ 
    if (e.Command == ApplicationCommands.Close || e.Command == DockablePaneCommands.Close) 
    { 
     e.Handled = true; 
     DockManager source = sender as DockManager; 
     if (source.ActiveContent != null) 
     { 
      source.ActiveContent.Close(); 
     } 
    } 
    else if (e.Command == DockablePaneCommands.Hide || e.Command == DockablePaneCommands.ToggleAutoHide) 
    { 
     e.Handled = true; 

} }

此处理程序在这里实际上是关闭正确的内容。由于某种原因,有时AvalonDock会关闭另一个内容,因为它具有焦点(点击十字架将不会关注您的内容,因此它会关闭当前重点内容......) 正如你所看到的,我只是覆盖事件并手动关闭我的组件

不幸的是,这不包括所有情况。我也有一些原因(你好马车AvalonDock)实际上赶上关闭按钮的点击,因为有一个边缘情况:如果你删除最后一个组件,你将无法添加一个新的组件,因为AvalonDock将删除最后剩下的面板。此外,如果你关闭了一个DockableContent,其中有很多标签,AvalonDock将关闭所有的标签,所以我必须实现一些东西才能关闭当前标签(这更有意义),我不得不为每个内容添加一个鼠标放下处理程序添加到赶上这个事件。用下面的技巧,我可以做一个变通方法来避免这个错误:

/// <summary> 
    /// Handler called when a DockableContent state changed. 
    /// We need it to define a PreviewMouseDownHandler for each DockablePane 
    /// possibly created (which are usually created upon docking a floating window 
    /// to a new position) in order to handle single DockableContent closing 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    void NewContent_StateChanged(object sender, RoutedEventArgs e) 
    { 
     DockableContent source = sender as DockableContent; 
     if (source.State == DockableContentState.Docked && source.Parent is DockablePane) 
     { 
      DockablePane parent = source.Parent as DockablePane; 
      parent.PreviewMouseDown -= mouseHandler; 
      parent.PreviewMouseDown += mouseHandler; 
     } 
    } 

    /// <summary> 
    /// Handler called on mouse down on a DockablePane. 
    /// It is designed to detect where did the user click, and 
    /// if he clicked on Close, only the current DockableContent will be closed 
    /// (unlike the native behavior which requires us to close the entire DockablePane 
    /// upon clicking on Close...) 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    void DockablePaneMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     DockablePane source = sender as DockablePane; 
     if (e.OriginalSource is AvalonDock.ImageEx) 
     { 
      //User clicked on one of the three icons on the top-right corner of the DockablePane 
      if ((e.OriginalSource as AvalonDock.ImageEx).Source.ToString().Contains("PinClose")) 
      { 
       RemoveFromUI(source.SelectedItem as DockableContent); 
       e.Handled = true; 
      } 
     } 
    } 

    /// <summary> 
    /// Removes a DockableContent from the currently displayed UI 
    /// (called when the original DockableItemsSource changed) 
    /// </summary> 
    /// <param name="content">The content to be removed</param> 
    private void RemoveFromUI(DockableContent content) 
    { 
     if (content == null) 
     { 
      return; 
     } 
     DockablePane parent = content.Parent as DockablePane; 
     if (this.ActiveContent == parent.SelectedItem) 
     { 
      this.ActiveContent = null; 
     } 
     (parent.SelectedItem as DockableContent).Close(); 
     //// If the current DockablePane is left empty, we ensure to close it 
     if (parent.Items.Count == 0) 
     { 
      //This case is needed if we are trying to remove the last DockablePane from a DockingManager 
      //Native behavior will NOT set the Content property if you remove the last DockablePane: 
      //it will therefore consider this CLOSED DockablePane as the current ActiveContent, 
      //and will try to add new contents in this closed pane, which seems rather disturbing. 
      //Here we explicitly set the Content property to null if we are removing the last element, 
      //so next time user adds a tab, it will be added as the new Content! 
      if (parent == this.Content) 
      { 
       this.Content = null; 
      } 
      parent.Close(); 
      parent.Visibility = Visibility.Hidden; 
     } 
    } 

再次,这是这种小事情令人难以置信的大的工作,但不幸的是,这AvalonDock远未生产环境准备和我不得不调整这些东西,使其工作。

希望它也能为你工作,并节省自己已经给这个问题一些头痛!

+0

谢谢,我会尝试这个工作,并希望它的工作(接受和upvoted,如果它当然:P)。 – 2012-08-16 20:45:48

+1

事实上,我将这个码头包含在我们的应用程序中的上面列出的调整中,它被部署了,并且没有人告诉我他们有一个大约1年的bug,所以我非常有信心=) – Damascus 2012-08-16 21:06:50

+0

谢谢大马士革。我喜欢你的信心:P – 2012-08-17 12:02:55

2

如果您使用的是MVVM方法阿瓦隆码头(第2版),那么你可以把这个在您的视图模型:

DockAsDocumentCommand = new DelegateCommand(() => { },() => false); 
AutoHideCommand = new DelegateCommand(() => { },() => false); 
CanClose = false; 
CanHide = false; 

这些都需要对他们的双向绑定和NotifyPropertyChanged。

一旦你这样做了关闭,隐藏和移动到另一个文档的所有选项将被删除或变灰。

1

如果使用MVVM,将其设置CanClose为false XAML就足够了,这样的:

 <avalondock:DockingManager.LayoutItemContainerStyleSelector> 
      <avalon:PanesStyleSelector> 
       <avalon:PanesStyleSelector.DeviceStyle> 
        <Style TargetType="{x:Type avalondock:LayoutItem}"> 
         <Setter Property="Title" Value="{Binding Model.Name}"/> 
         <Setter Property="ToolTip" Value="{Binding Model.Name}"/> 
         <Setter Property="ContentId" Value="{Binding Model.Id}"/> 
         <Setter Property="CanClose" Value="False"></Setter> 
        </Style> 
       </avalon:PanesStyleSelector.DeviceStyle> 
      </avalon:PanesStyleSelector> 
     </avalondock:DockingManager.LayoutItemContainerStyleSelector> 
0

另一种方式来摆脱CloseCloseAllCloseAllButThis命令是他们的命令设置为null在LayoutItemContainerStyleSelector 。喜欢的东西:

<xcad:DockingManager.LayoutItemContainerStyleSelector> 
    <local:PanesStyleSelector> 
     <local:PanesStyleSelector.DocStyle> 
      <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}"/> 
      <Setter Property="CloseAllCommand" Value="{x:Null}" /> 
      <Setter Property="CloseAllButThisCommand" Value="{x:Null}" /> 
     </Style> 
     </local:PanesStyleSelector.DrawingStyle> 
    </local:PanesStyleSelector> 
    </xcad:DockingManager.LayoutItemContainerStyleSelector> 

PanesStyleSelector是一个简单的StyleSelector(我有多个款式取决于面板类型选择,所以我需要一个StyleSelector,你可以跳过它,如果你只有一个类型的窗格。以下是简化版本):

Public Class PanesStyleSelector 
    Inherits StyleSelector 

    Public Property DocStyle() As Style 

    Public Overrides Function SelectStyle(item As Object, container As System.Windows.DependencyObject) As System.Windows.Style 
    Return DocStyle 
    End Function 
End Class 

这将在文档选项卡的上下文菜单中禁用这两个CloseAllCloseAllButThis命令。还请注意,我正在处理我的虚拟机中的CloseCommand,我可以决定是关闭文档还是提示用户。这将消除意外点击关闭按钮。

相关问题