Skip to content

Commit

Permalink
FixVisibilityBindings Fix visibility bindings of undocked panels in s…
Browse files Browse the repository at this point in the history
…pecific cases.
  • Loading branch information
scdmitryvodich committed Aug 7, 2019
1 parent e6c9438 commit 0856e36
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 )
{
Expand Down Expand Up @@ -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();
}
};

Expand Down Expand Up @@ -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<LayoutAnchorablePane>().First( p => p.ChildrenCount > 0 && p.SelectedContent != null ).SelectedContent.IsActive = true;
var anchorablePane = _model.Descendents().OfType<LayoutAnchorablePane>()
.FirstOrDefault( p => p.ChildrenCount > 0 && p.SelectedContent != null );
if( anchorablePane != null )
{
anchorablePane.SelectedContent.IsActive = true;
}
handled = true;
}
break;
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand All @@ -390,12 +391,6 @@ private void _anchorable_IsVisibleChanged( object sender, EventArgs e )
}
}







#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,14 @@ private void UpdateDragPosition()

#endregion

public virtual void EnableBindings()
{
}

public virtual void DisableBindings()
{
}

#region Internal Classes

protected internal class FloatingWindowContentHost : HwndHost
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
38 changes: 32 additions & 6 deletions source/Components/Xceed.Wpf.AvalonDock/DockingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenCon
private AutoHideWindowManager _autoHideWindowManager;
private FrameworkElement _autohideArea;
private List<LayoutFloatingWindowControl> _fwList = new List<LayoutFloatingWindowControl>();
private List<LayoutFloatingWindowControl> _fwHiddenList = new List<LayoutFloatingWindowControl>();
private OverlayWindow _overlayWindow = null;
private List<IDropArea> _areas = null;
private bool _insideInternalSetActiveContent = false;
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down

0 comments on commit 0856e36

Please sign in to comment.