Remove AvalonDock Dock and Close Buttons

I would like to remove them, as this causes me a lot of problems. If there is a way to solve it, I will be happy to try it. The first few minutes of use I received as 3 different exceptions, and I cannot figure out how to remove these damned options.

Pinning and undoing and pinning throws an InvalidOperationException, because the operation is invalid due to the current state of the object.

Sometimes commit and cancel open a dialog box and ask me for a file, I don’t want this to happen, but it happens and it throws an exception.

I accidentally press the close button and I cannot return the window. This is really frustrating. I'm sure other Avalondock users have come across this.

And since I don’t want to spend too much time, I will ask right here. How did you get around these exceptions or removed these buttons? Thanks.

+4
source share
4 answers

I had the same problem as you. Not wanting to remove the icons from the actual interface, I just disabled them with event handlers

This is how I worked:

To remove Hide and AutoHide commands:

I added the following handler:

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

Here is what ContentClosing looks like:

 /// <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; 

}}

This handler was here to actually close the correct content. For some reason, sometimes AvalonDock closes other content because it has focus (clicking on the cross will not give focus to your content, and thus it will close the current focused content ...) As you can see, I just redefine the events and I close my components manually

Unfortunately, this does not apply to all cases. I also, for some reason (hello buggy AvalonDock) actually caught a click on the close button, because there is an edge. If you remove the last component, you cannot add a new component because AvalonDock will delete the last remaining panel. Moreover, if you close the DockableContent with many tabs in it, AvalonDock will close all the tabs, so I had to implement something to just close the current tab (which makes imho more sense) I had to add a mouse down handler for each content added so that catch this event. Following the trick, I could do a workaround to avoid this error:

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

Again, this is an incredible lot of work for such small things, but unfortunately this AvalonDock is far from the finished production environment, and I had to configure such things to make it work.

Hope this works for you, too, and save some of the headaches that I already gave this problem!

+3
source

If you use the MVVM approach to the Avalon dock (version 2), you can put this in your view model:

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

All of these need to have TwoWay and NotifyPropertyChanged bindings.

After that, all options for closing, hiding and switching to another document will be deleted or grayed out.

+2
source

If you use MVVM, just set CanClose to false in XAML, for example:

  <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> 
+1
source

Another way to get rid of the Close , CloseAll and CloseAllButThis is to set their commands to null in LayoutItemContainerStyleSelector . Sort of:

 <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 is a simple StyleSelector (I had several styles to choose depending on the type of panel, so I needed a StyleSelector , you can skip it if you have only one type of panel. Is a simplified version.):

 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 

This will disable the CloseAll and CloseAllButThis in the document tab context menu. Also note that I am processing CloseCommand in my virtual machine, and I can decide whether to close my document or perhaps ask the user. This will save you from accidentally clicking the close button.

0
source

All Articles