diff --git a/DialogHost.Avalonia/DialogHost.axaml b/DialogHost.Avalonia/DialogHost.axaml index cf1772f..deec377 100644 --- a/DialogHost.Avalonia/DialogHost.axaml +++ b/DialogHost.Avalonia/DialogHost.axaml @@ -25,11 +25,8 @@ - - - + + diff --git a/DialogHost.Avalonia/DialogHostStyles.axaml.cs b/DialogHost.Avalonia/DialogHostStyles.axaml.cs index 79c01da..d20a540 100644 --- a/DialogHost.Avalonia/DialogHostStyles.axaml.cs +++ b/DialogHost.Avalonia/DialogHostStyles.axaml.cs @@ -1,5 +1,8 @@ -using Avalonia.Controls; +using System.Collections.Generic; +using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; +using Avalonia.Media; using Avalonia.Styling; namespace DialogHostAvalonia { @@ -19,7 +22,7 @@ namespace DialogHostAvalonia { /// </Application> /// /// - public class DialogHostStyles : Styles { + public class DialogHostStyles : Styles, IResourceNode { /// public DialogHostStyles() { AvaloniaXamlLoader.Load(this); @@ -29,5 +32,56 @@ public DialogHostStyles() { public DialogHostStyles(IResourceHost owner) : base(owner) { AvaloniaXamlLoader.Load(this); } + + /// + /// Lists of resource keys which will be used as defaults for DialogHost.Background property + /// + public static IReadOnlyList BackgroundColorKeys { get; } = ["SystemControlPageBackgroundChromeLowBrush"]; + + /// + /// Lists of resource keys which will be used as defaults for DialogHost.OverlayBackground property + /// + public static IReadOnlyList OverlayBackgroundColorKeys { get; } = + ["SystemControlBackgroundAltHighBrush", "MaterialDesignPaper", "MaterialPaperBrush"]; + + bool IResourceNode.HasResources => true; + + /// + /// Tries to find a resource within the object. + /// + /// The resource key. + /// Theme used to select theme dictionary. + /// + /// When this method returns, contains the value associated with the specified key, + /// if the key is found; otherwise, null. + /// + /// + /// True if the resource if found, otherwise false. + /// + bool IResourceNode.TryGetResource(object key, ThemeVariant? theme, out object? value) { + if (key is "DialogHostBackgroundMixinBrush") { + foreach (var colorKey in BackgroundColorKeys) { + if (Application.Current!.TryGetResource(colorKey, theme, out value)) { + return true; + } + } + + value = Brushes.Black; + return true; + } + + if (key is "DialogHostOverlayBackgroundMixinBrush") { + foreach (var colorKey in OverlayBackgroundColorKeys) { + if (Application.Current!.TryGetResource(colorKey, theme, out value)) { + return true; + } + } + + value = Brushes.Black; + return true; + } + + return base.TryGetResource(key, theme, out value); + } } } \ No newline at end of file diff --git a/DialogHost.Avalonia/Utilities/MultiDynamicResourceExtension.cs b/DialogHost.Avalonia/Utilities/MultiDynamicResourceExtension.cs deleted file mode 100644 index c005eff..0000000 --- a/DialogHost.Avalonia/Utilities/MultiDynamicResourceExtension.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using Avalonia.Markup.Xaml.Converters; -using Avalonia.Media; -using Avalonia.Styling; - -namespace DialogHostAvalonia.Utilities -{ - /// - /// Allows binding to several different DynamicResources - /// - // TODO: Replace it with proper implementation when https://github.com/AvaloniaUI/Avalonia/issues/15270 will be resolved - internal class MultiDynamicResourceExtension : MarkupExtension - { - public IBrush DefaultBrush { get; set; } - - public object ResourceKeys { get; set; } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - var provideValueTarget = serviceProvider.GetService(); - if (provideValueTarget is null) - { - throw new InvalidOperationException( - "Can't resolve IProvideValueTarget from Avalonia service provider."); - } - - var setter = (Setter)provideValueTarget.TargetObject; - var targetProperty = setter.Property; - - if (ResourceKeys is not string resourceKey) - { - throw new InvalidOperationException( - "ResourceKeys should be string with ; delimeter"); - } - - var resourceKeys = resourceKey.Split(';'); - var source = resourceKeys - .Select(key => Application.Current! - .GetResourceObservable(key, GetConverter(targetProperty))); - var testObservable = new MultiDynamicResourceObservable(source, DefaultBrush); - return testObservable.ToBinding(); - } - - private static Func? GetConverter(AvaloniaProperty? targetProperty) - { - if (targetProperty?.PropertyType == typeof(IBrush)) - { - return x => ColorToBrushConverter.Convert(x, typeof(IBrush)); - } - - return null; - } - - public sealed class MultiDynamicResourceObservable : IObservable, IDisposable - { - public MultiDynamicResourceObservable(IEnumerable> observables, object? defaultValue) - { - var dictionary = observables.ToDictionary(observable => observable, _ => (object?)null); - var disposables = dictionary.Keys - .Select(obs => obs - .Subscribe(o => - { - dictionary[obs] = o; - var newValue = - dictionary.Values.LastOrDefault(o1 => o1 is not UnsetValueType && o1 is not null) ?? - defaultValue; - _subject.OnNext(newValue); - })) - .ToList(); - _disposable = new CompositeDisposable(disposables); - } - - private readonly CompositeDisposable _disposable; - private readonly BehaviorSubject _subject = new(null); - - /// - public IDisposable Subscribe(IObserver observer) - { - return _subject.Subscribe(observer); - } - - /// - public void Dispose() - { - _disposable.Dispose(); - _subject.Dispose(); - } - } - } -} \ No newline at end of file