diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 9ad1a99e..3ffacc74 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -51,6 +51,7 @@ internal LayoutAnchorableFloatingWindowControl( LayoutAnchorableFloatingWindow m _model = model; HideWindowCommand = new RelayCommand( ( p ) => OnExecuteHideWindowCommand( p ), ( p ) => CanExecuteHideWindowCommand( p ) ); CloseWindowCommand = new RelayCommand( ( p ) => OnExecuteCloseWindowCommand( p ), ( p ) => CanExecuteCloseWindowCommand( p ) ); + Activated += LayoutAnchorableFloatingWindowControl_Activated; UpdateThemeResources(); MinWidth = _model.RootPanel.CalculatedDockMinWidth(); MinHeight = _model.RootPanel.CalculatedDockMinHeight(); @@ -71,6 +72,17 @@ private void OnRootUpdated(object sender, EventArgs e) } } + private void LayoutAnchorableFloatingWindowControl_Activated( object sender, EventArgs e ) + { + // Issue similar to: http://avalondock.codeplex.com/workitem/15036 + var visibilityBinding = GetBindingExpression( VisibilityProperty ); + + if ( visibilityBinding == null && Visibility == Visibility.Visible ) + { + SetVisibilityBinding(); + } + } + internal LayoutAnchorableFloatingWindowControl( LayoutAnchorableFloatingWindow model) : this( model, false ) { @@ -147,9 +159,9 @@ protected override void OnInitialized( EventArgs e ) IsVisibleChanged += ( s, args ) => { var visibilityBinding = GetBindingExpression( VisibilityProperty ); - if( IsVisible && ( visibilityBinding == null ) ) + if( visibilityBinding == null && IsVisible ) { - SetBinding( VisibilityProperty, new Binding( "IsVisible" ) { Source = _model, Converter = new BoolToVisibilityConverter(), Mode = BindingMode.OneWay, ConverterParameter = Visibility.Hidden } ); + SetVisibilityBinding(); } }; @@ -213,7 +225,12 @@ protected override IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, In case Win32Helper.WM_NCLBUTTONDOWN: //Left button down on title -> start dragging over docking manager if( wParam.ToInt32() == Win32Helper.HT_CAPTION ) { - _model.Descendents().OfType().First( p => p.ChildrenCount > 0 && p.SelectedContent != null ).SelectedContent.IsActive = true; + var anchorablePane = _model.Descendents().OfType() + .FirstOrDefault( p => p.ChildrenCount > 0 && p.SelectedContent != null ); + if( anchorablePane != null ) + { + anchorablePane.SelectedContent.IsActive = true; + } handled = true; } break; @@ -308,6 +325,59 @@ private bool IsContextMenuOpen() return false; } + private void SetVisibilityBinding() + { + SetBinding( + VisibilityProperty, + new Binding("IsVisible") + { + Source = _model, + Converter = new BoolToVisibilityConverter(), + Mode = BindingMode.OneWay, + ConverterParameter = Visibility.Hidden + } + ); + } + + #endregion + + #region Public Methods + + public override void EnableBindings() + { + _model.PropertyChanged += _model_PropertyChanged; + SetVisibilityBinding(); + var root = Model.Root; + if( root != null ) + { + LayoutRoot layoutRoot = root as LayoutRoot; + if ( layoutRoot != null ) + { + layoutRoot.Updated += OnRootUpdated; + } + } + + base.EnableBindings(); + } + + public override void DisableBindings() + { + var root = Model.Root; + if( root != null ) + { + LayoutRoot layoutRoot = root as LayoutRoot; + if( layoutRoot != null ) + { + layoutRoot.Updated -= OnRootUpdated; + } + } + + BindingOperations.ClearBinding( _model, VisibilityProperty ); + _model.PropertyChanged -= _model_PropertyChanged; + + base.DisableBindings(); + } + #endregion #region Commands diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs index 62824834..e8bf609e 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs @@ -32,6 +32,7 @@ public class LayoutAnchorableItem : LayoutItem private ICommand _defaultAutoHideCommand; private ICommand _defaultDockCommand; private ReentrantFlag _visibilityReentrantFlag = new ReentrantFlag(); + private ReentrantFlag _anchorableVisibilityReentrantFlag = new ReentrantFlag(); #endregion @@ -377,9 +378,9 @@ private void _anchorable_IsVisibleChanged( object sender, EventArgs e ) { if( _anchorable != null && _anchorable.Root != null ) { - if( _visibilityReentrantFlag.CanEnter ) + if( _anchorableVisibilityReentrantFlag.CanEnter ) { - using( _visibilityReentrantFlag.Enter() ) + using( _anchorableVisibilityReentrantFlag.Enter() ) { if( _anchorable.IsVisible ) Visibility = Visibility.Visible; @@ -390,12 +391,6 @@ private void _anchorable_IsVisibleChanged( object sender, EventArgs e ) } } - - - - - - #endregion } } diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs index 844b1b9f..7b72a153 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -531,6 +531,14 @@ private void UpdateDragPosition() #endregion + public virtual void EnableBindings() + { + } + + public virtual void DisableBindings() + { + } + #region Internal Classes protected internal class FloatingWindowContentHost : HwndHost diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs index 962b5ab7..d00eecc0 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs @@ -641,12 +641,17 @@ private bool IsChildVisible(int index) { if( Orientation == Orientation.Horizontal ) { - return ColumnDefinitions[index].Width.IsStar || ColumnDefinitions[index].Width.Value > 0; + if ( index < ColumnDefinitions.Count ) + { + return ColumnDefinitions[ index ].Width.IsStar || ColumnDefinitions[ index ].Width.Value > 0; + } } - else + else if( index < RowDefinitions.Count ) { return RowDefinitions[ index ].Height.IsStar || RowDefinitions[ index ].Height.Value > 0; } + + return false; } private void ShowResizerOverlayWindow( LayoutGridResizerControl splitter ) diff --git a/source/Components/Xceed.Wpf.AvalonDock/DockingManager.cs b/source/Components/Xceed.Wpf.AvalonDock/DockingManager.cs index 097ccb6b..814a0126 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/DockingManager.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/DockingManager.cs @@ -43,6 +43,7 @@ public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenCon private AutoHideWindowManager _autoHideWindowManager; private FrameworkElement _autohideArea; private List _fwList = new List(); + private List _fwHiddenList = new List(); private OverlayWindow _overlayWindow = null; private List _areas = null; private bool _insideInternalSetActiveContent = false; @@ -2378,6 +2379,19 @@ private void DockingManager_Loaded( object sender, RoutedEventArgs e ) SetupAutoHideWindow(); + foreach( var fwc in _fwHiddenList ) + { + fwc.EnableBindings(); + if( fwc.KeepContentVisibleOnClose ) + { + fwc.Show(); + fwc.KeepContentVisibleOnClose = false; + } + + _fwList.Add( fwc ); + } + _fwHiddenList.Clear(); + //load windows not already loaded! foreach( var fw in Layout.FloatingWindows.Where( fw => !_fwList.Any( fwc => fwc.Model == fw ) ) ) _fwList.Add( CreateUIElementForModel( fw ) as LayoutFloatingWindowControl ); @@ -2421,13 +2435,25 @@ private void DockingManager_Unloaded( object sender, RoutedEventArgs e ) foreach( var fw in _fwList.ToArray() ) { - //fw.Owner = null; - fw.SetParentWindowToNull(); - fw.KeepContentVisibleOnClose = true; - // To avoid calling Close method multiple times. - fw.InternalClose(true); + ////fw.Owner = null; + //fw.SetParentWindowToNull(); + //fw.KeepContentVisibleOnClose = true; + //// To avoid calling Close method multiple times. + //fw.InternalClose(true); + + // Unloaded can occure not only after closing of the application, but after switching between tabs. + // For such case it's better to hide the floating windows instead of closing it. + // We clear bindings on visibility during the owner is unloaded. + if( fw.IsVisible ) + { + fw.KeepContentVisibleOnClose = true; + fw.Hide(); + } + fw.DisableBindings(); + _fwHiddenList.Add( fw ); } - _fwList.Clear(); + + _fwList.Clear(); DestroyOverlayWindow(); FocusElementManager.FinalizeFocusManagement( this );