@@ -269,9 +269,12 @@ static void OnTransformChanged(BindableObject bindable, object oldValue, object
269269 BindableProperty . Create ( "TransformOrigin" , typeof ( Point ) , typeof ( VisualElement ) , new Point ( .5d , .5d ) ,
270270 propertyChanged : ( b , o , n ) => { ( ( ( VisualElement ) b ) . AnchorX , ( ( VisualElement ) b ) . AnchorY ) = ( Point ) n ; } ) ;
271271
272+ bool _isVisibleExplicit = ( bool ) IsVisibleProperty . DefaultValue ;
273+
272274 /// <summary>Bindable property for <see cref="IsVisible"/>.</summary>
273275 public static readonly BindableProperty IsVisibleProperty = BindableProperty . Create ( nameof ( IsVisible ) , typeof ( bool ) , typeof ( VisualElement ) , true ,
274- propertyChanged : ( bindable , oldvalue , newvalue ) => ( ( VisualElement ) bindable ) . OnIsVisibleChanged ( ( bool ) oldvalue , ( bool ) newvalue ) ) ;
276+ propertyChanged : ( bindable , oldvalue , newvalue ) => ( ( VisualElement ) bindable ) . OnIsVisibleChanged ( ( bool ) oldvalue , ( bool ) newvalue ) ,
277+ coerceValue : CoerceIsVisibleProperty ) ;
275278
276279 /// <summary>Bindable property for <see cref="Opacity"/>.</summary>
277280 public static readonly BindableProperty OpacityProperty = BindableProperty . Create ( nameof ( Opacity ) , typeof ( double ) , typeof ( VisualElement ) , 1d , coerceValue : ( bindable , value ) => ( ( double ) value ) . Clamp ( 0 , 1 ) ) ;
@@ -694,6 +697,36 @@ private protected bool InputTransparentCore
694697 }
695698 }
696699
700+ /// <summary>
701+ /// This value represents the cumulative IsVisible value.
702+ /// All types that override this property need to also invoke
703+ /// the RefreshIsVisibleProperty() method if the value will change.
704+ /// </summary>
705+ private protected bool IsVisibleCore
706+ {
707+ get
708+ {
709+ if ( _isVisibleExplicit == false )
710+ {
711+ // If the explicitly set value is false, then nothing else matters
712+ // And we can save the effort of a Parent check
713+ return false ;
714+ }
715+
716+ var parent = Parent as VisualElement ;
717+ while ( parent is not null )
718+ {
719+ if ( ! parent . IsVisible )
720+ {
721+ return false ;
722+ }
723+ parent = parent . Parent as VisualElement ;
724+ }
725+
726+ return _isVisibleExplicit ;
727+ }
728+ }
729+
697730 /// <summary>
698731 /// Gets a value indicating whether this element is focused currently. This is a bindable property.
699732 /// </summary>
@@ -1499,6 +1532,7 @@ internal virtual void OnIsVisibleChanged(bool oldValue, bool newValue)
14991532 fe . Handler ? . UpdateValue ( nameof ( IView . Visibility ) ) ;
15001533 }
15011534
1535+ ( this as IPropertyPropagationController ) ? . PropagatePropertyChanged ( IsVisibleProperty . PropertyName ) ;
15021536 InvalidateMeasureInternal ( InvalidationTrigger . Undefined ) ;
15031537 }
15041538
@@ -1663,6 +1697,17 @@ static object CoerceInputTransparentProperty(BindableObject bindable, object val
16631697 return false ;
16641698 }
16651699
1700+ static object CoerceIsVisibleProperty ( BindableObject bindable , object value )
1701+ {
1702+ if ( bindable is VisualElement visualElement )
1703+ {
1704+ visualElement . _isVisibleExplicit = ( bool ) value ;
1705+ return visualElement . IsVisibleCore ;
1706+ }
1707+
1708+ return false ;
1709+ }
1710+
16661711 static void OnInputTransparentPropertyChanged ( BindableObject bindable , object oldValue , object newValue )
16671712 {
16681713 ( bindable as IPropertyPropagationController ) ? . PropagatePropertyChanged ( VisualElement . InputTransparentProperty . PropertyName ) ;
@@ -1730,6 +1775,9 @@ void IPropertyPropagationController.PropagatePropertyChanged(string propertyName
17301775 if ( propertyName == null || propertyName == InputTransparentProperty . PropertyName )
17311776 this . RefreshPropertyValue ( InputTransparentProperty , _inputTransparentExplicit ) ;
17321777
1778+ if ( propertyName == null || propertyName == IsVisibleProperty . PropertyName )
1779+ this . RefreshPropertyValue ( IsVisibleProperty , _isVisibleExplicit ) ;
1780+
17331781 PropertyPropagationExtensions . PropagatePropertyChanged ( propertyName , this , ( ( IVisualTreeElement ) this ) . GetVisualChildren ( ) ) ;
17341782 }
17351783
@@ -1740,6 +1788,13 @@ void IPropertyPropagationController.PropagatePropertyChanged(string propertyName
17401788 protected void RefreshIsEnabledProperty ( ) =>
17411789 this . RefreshPropertyValue ( IsEnabledProperty , _isEnabledExplicit ) ;
17421790
1791+ /// <summary>
1792+ /// This method must always be called if some event occurs and the value of
1793+ /// the <see cref="IsVisibleCore"/> property will change.
1794+ /// </summary>
1795+ internal void RefreshIsVisibleProperty ( ) =>
1796+ this . RefreshPropertyValue ( IsVisibleProperty , _isVisibleExplicit ) ;
1797+
17431798 /// <summary>
17441799 /// This method must always be called if some event occurs and the value of
17451800 /// the InputTransparentCore property will change.
0 commit comments