@@ -253,8 +253,19 @@ public void RemoveBinding(BindableProperty property)
253253 {
254254 BindablePropertyContext context = GetContext ( property ?? throw new ArgumentNullException ( nameof ( property ) ) ) ;
255255
256- if ( context ? . Binding != null )
257- RemoveBinding ( property , context ) ;
256+ var specificity = SetterSpecificity . FromBinding ;
257+ if ( context != null && context . Bindings . Count > 0 )
258+ specificity = context . Bindings . Last ( ) . Key ;
259+
260+ RemoveBinding ( property , specificity ) ;
261+ }
262+
263+ internal void RemoveBinding ( BindableProperty property , SetterSpecificity specificity )
264+ {
265+ BindablePropertyContext context = GetContext ( property ?? throw new ArgumentNullException ( nameof ( property ) ) ) ;
266+
267+ if ( context != null && context . Bindings . Count > 0 )
268+ RemoveBinding ( property , context , specificity ) ;
258269 }
259270
260271 /// <summary>
@@ -286,11 +297,24 @@ internal void SetBinding(BindableProperty targetProperty, BindingBase binding, S
286297 context . Values [ SetterSpecificity . FromBinding ] = kvp . Value ;
287298 }
288299
289- context . Binding ? . Unapply ( ) ;
290- context . BindingSpecificity = specificity ;
300+ BindingBase oldBinding = null ;
301+ SetterSpecificity oldSpecificity = default ;
302+ if ( context . Bindings . Count > 0 )
303+ {
304+ var b_p = context . Bindings . Last ( ) ;
305+ oldSpecificity = b_p . Key ;
306+ oldBinding = b_p . Value ;
307+ }
308+
309+ if ( oldBinding != null && specificity . CompareTo ( oldSpecificity ) < 0 )
310+ {
311+ context . Bindings [ specificity ] = binding ;
312+ return ;
313+ }
314+
315+ oldBinding ? . Unapply ( ) ;
291316
292- BindingBase oldBinding = context . Binding ;
293- context . Binding = binding ?? throw new ArgumentNullException ( nameof ( binding ) ) ;
317+ context . Bindings [ specificity ] = binding ?? throw new ArgumentNullException ( nameof ( binding ) ) ;
294318
295319 targetProperty . BindingChanging ? . Invoke ( this , oldBinding , binding ) ;
296320
@@ -319,9 +343,11 @@ public static void SetInheritedBindingContext(BindableObject bindable, object va
319343 if ( bpContext != null && oldContext == null )
320344 oldContext = bpContext . Values . LastOrDefault ( ) . Value ;
321345
322- if ( bpContext != null && bpContext . Binding != null )
346+ var binding = bpContext ? . Bindings . Values . LastOrDefault ( ) ;
347+
348+ if ( binding != null )
323349 {
324- bpContext . Binding . Context = value ;
350+ binding . Context = value ;
325351 bindable . _inheritedContext = null ;
326352 }
327353 else
@@ -372,12 +398,7 @@ protected virtual void OnPropertyChanging([CallerMemberName] string propertyName
372398 protected void UnapplyBindings ( )
373399 {
374400 foreach ( var context in _properties . Values )
375- {
376- if ( context . Binding == null )
377- continue ;
378-
379- context . Binding . Unapply ( ) ;
380- }
401+ context . Bindings . Values . LastOrDefault ( ) ? . Unapply ( ) ;
381402 }
382403
383404 internal bool GetIsBound ( BindableProperty targetProperty )
@@ -386,7 +407,7 @@ internal bool GetIsBound(BindableProperty targetProperty)
386407 throw new ArgumentNullException ( nameof ( targetProperty ) ) ;
387408
388409 BindablePropertyContext bpcontext = GetContext ( targetProperty ) ;
389- return bpcontext != null && bpcontext . Binding != null ;
410+ return bpcontext != null && bpcontext . Bindings . Count > 0 ;
390411 }
391412
392413 internal virtual void OnRemoveDynamicResource ( BindableProperty property )
@@ -398,6 +419,9 @@ internal virtual void OnSetDynamicResource(BindableProperty property, string key
398419 }
399420
400421 internal void RemoveDynamicResource ( BindableProperty property )
422+ => RemoveDynamicResource ( property , SetterSpecificity . DynamicResourceSetter ) ;
423+
424+ internal void RemoveDynamicResource ( BindableProperty property , SetterSpecificity specificity )
401425 {
402426 if ( property == null )
403427 throw new ArgumentNullException ( nameof ( property ) ) ;
@@ -595,7 +619,7 @@ void SetValueActual(BindableProperty property, BindablePropertyContext context,
595619 if ( ( context . Attributes & BindableContextAttributes . IsDynamicResource ) != 0 && clearDynamicResources )
596620 RemoveDynamicResource ( property ) ;
597621
598- BindingBase binding = context . Binding ;
622+ BindingBase binding = context . Bindings . Values . LastOrDefault ( ) ;
599623
600624 if ( ! silent && ( ! sameValue || raiseOnEqual ) )
601625 {
@@ -618,15 +642,18 @@ internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChan
618642 for ( int i = 0 , propLength = prop . Length ; i < propLength ; i ++ )
619643 {
620644 BindablePropertyContext context = prop [ i ] ;
621- BindingBase binding = context . Binding ;
645+ var kvp = context . Bindings . LastOrDefault ( ) ;
646+ var specificity = kvp . Key ;
647+ var binding = kvp . Value ;
648+
622649 if ( binding == null )
623650 continue ;
624651
625652 if ( skipBindingContext && ReferenceEquals ( context . Property , BindingContextProperty ) )
626653 continue ;
627654
628655 binding . Unapply ( fromBindingContextChanged : fromBindingContextChanged ) ;
629- binding . Apply ( BindingContext , this , context . Property , fromBindingContextChanged , context . BindingSpecificity ) ;
656+ binding . Apply ( BindingContext , this , context . Property , fromBindingContextChanged , specificity ) ;
630657 }
631658 }
632659
@@ -669,13 +696,31 @@ BindablePropertyContext CreateAndAddContext(BindableProperty property)
669696 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
670697 BindablePropertyContext GetOrCreateContext ( BindableProperty property ) => GetContext ( property ) ?? CreateAndAddContext ( property ) ;
671698
672- void RemoveBinding ( BindableProperty property , BindablePropertyContext context )
699+ void RemoveBinding ( BindableProperty property , BindablePropertyContext context , SetterSpecificity specificity )
673700 {
674- context . Binding . Unapply ( ) ;
701+ var count = context . Bindings . Count ;
675702
676- property . BindingChanging ? . Invoke ( this , context . Binding , null ) ;
703+ if ( count == 0 )
704+ return ; //used to fail;
705+
706+ var currentbinding = context . Bindings . Values . Last ( ) ;
707+ var binding = context . Bindings [ specificity ] ;
708+ var isCurrent = binding == currentbinding ;
709+
710+ if ( isCurrent )
711+ {
712+ binding . Unapply ( ) ;
713+
714+ currentbinding = null ;
715+ if ( count > 1 )
716+ currentbinding = context . Bindings . Values . ElementAt ( count - 2 ) ;
717+
718+ property . BindingChanging ? . Invoke ( this , binding , currentbinding ) ;
719+
720+ currentbinding ? . Apply ( BindingContext , this , property , false , context . Bindings . Keys . ElementAt ( count - 2 ) ) ;
721+ }
677722
678- context . Binding = null ;
723+ context . Bindings . Remove ( specificity ) ;
679724 }
680725
681726 /// <summary>
@@ -740,9 +785,7 @@ internal class BindablePropertyContext
740785 {
741786 public BindableContextAttributes Attributes ;
742787
743- //TODO should be a list of bindings/specificity
744- public BindingBase Binding ;
745- public SetterSpecificity BindingSpecificity = SetterSpecificity . FromBinding ;
788+ public SortedList < SetterSpecificity , BindingBase > Bindings = new ( ) ;
746789
747790 public Queue < SetValueArgs > DelayedSetters ;
748791 public BindableProperty Property ;
0 commit comments