2012-08-16 88 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,我可以決定是關閉文檔還是提示用戶。這將消除意外點擊關閉按鈕。

相關問題