@ -5,9 +5,11 @@ using System;
using System.Collections.Generic ;
using System.Collections.Specialized ;
using System.Reactive ;
using System.Reactive.Disposables ;
using System.Reactive.Linq ;
using System.Reflection ;
using System.Text ;
using Avalonia.Collections ;
namespace Avalonia.Styling
{
@ -122,14 +124,7 @@ namespace Avalonia.Styling
{
if ( subscribe )
{
var observable = Observable . FromEventPattern <
NotifyCollectionChangedEventHandler ,
NotifyCollectionChangedEventArgs > (
x = > control . Classes . CollectionChanged + = x ,
x = > control . Classes . CollectionChanged - = x )
. StartWith ( ( EventPattern < NotifyCollectionChangedEventArgs > ) null )
. Select ( _ = > Matches ( control . Classes ) )
. DistinctUntilChanged ( ) ;
var observable = new ClassObserver ( control . Classes , _ classes . Value ) ;
return new SelectorMatch ( observable ) ;
}
else
@ -204,5 +199,64 @@ namespace Avalonia.Styling
return builder . ToString ( ) ;
}
private class ClassObserver : IObservable < bool >
{
readonly IList < string > _ match ;
readonly List < IObserver < bool > > _ observers = new List < IObserver < bool > > ( ) ;
IAvaloniaReadOnlyList < string > _ classes ;
public ClassObserver ( IAvaloniaReadOnlyList < string > classes , IList < string > match )
{
_ classes = classes ;
_ match = match ;
}
public IDisposable Subscribe ( IObserver < bool > observer )
{
if ( _ observers . Count = = 0 )
{
_ classes . CollectionChanged + = ClassesChanged ;
}
_ observers . Add ( observer ) ;
observer . OnNext ( GetResult ( ) ) ;
return Disposable . Create ( ( ) = >
{
_ observers . Remove ( observer ) ;
if ( _ observers . Count = = 0 )
{
_ classes . CollectionChanged - = ClassesChanged ;
}
} ) ;
}
private void ClassesChanged ( object sender , NotifyCollectionChangedEventArgs e )
{
if ( e . Action ! = NotifyCollectionChangedAction . Move )
{
foreach ( var observer in _ observers )
{
observer . OnNext ( GetResult ( ) ) ;
}
}
}
private bool GetResult ( )
{
int remaining = _ match . Count ;
foreach ( var c in _ classes )
{
if ( _ match . Contains ( c ) )
{
- - remaining ;
}
}
return remaining = = 0 ;
}
}
}
}