From 704d929e308b0c3af63c2fd56000fad53e80ab3d Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 27 Jun 2020 12:13:14 +0200 Subject: [PATCH] Allow batch updating resources. --- samples/ControlCatalog/MainView.xaml.cs | 4 ++++ src/Avalonia.Controls/Application.cs | 18 +++++++++++++++++- src/Avalonia.Styling/Controls/IResourceHost.cs | 14 ++++++++++++++ src/Avalonia.Styling/StyledElement.cs | 18 ++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs index b0c205246e..ef9db1e31b 100644 --- a/samples/ControlCatalog/MainView.xaml.cs +++ b/samples/ControlCatalog/MainView.xaml.cs @@ -35,6 +35,8 @@ namespace ControlCatalog var themes = this.Find("Themes"); themes.SelectionChanged += (sender, e) => { + ((IResourceHost)Application.Current).BeginBatchUpdate(); + switch (themes.SelectedIndex) { case 0: @@ -50,6 +52,8 @@ namespace ControlCatalog Application.Current.Styles[0] = App.DefaultDark; break; } + + ((IResourceHost)Application.Current).EndBatchUpdate(); }; var decorations = this.Find("Decorations"); diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 3bf72460df..6009f5c0e0 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -43,6 +43,7 @@ namespace Avalonia private Styles _styles; private IResourceDictionary _resources; private bool _notifyingResourcesChanged; + private int _resourceBatchUpdate; private Action> _stylesAdded; private Action> _stylesRemoved; @@ -199,9 +200,24 @@ namespace Avalonia Styles.TryGetResource(key, out value); } + /// + void IResourceHost.BeginBatchUpdate() => ++_resourceBatchUpdate; + + /// + void IResourceHost.EndBatchUpdate() + { + if (_resourceBatchUpdate > 0 && --_resourceBatchUpdate == 0) + { + ResourcesChanged?.Invoke(this, ResourcesChangedEventArgs.Empty); + } + } + void IResourceHost.NotifyHostedResourcesChanged(ResourcesChangedEventArgs e) { - ResourcesChanged?.Invoke(this, e); + if (_resourceBatchUpdate == 0) + { + ResourcesChanged?.Invoke(this, e); + } } void IStyleHost.StylesAdded(IReadOnlyList styles) diff --git a/src/Avalonia.Styling/Controls/IResourceHost.cs b/src/Avalonia.Styling/Controls/IResourceHost.cs index fed9359d94..00d599aaf1 100644 --- a/src/Avalonia.Styling/Controls/IResourceHost.cs +++ b/src/Avalonia.Styling/Controls/IResourceHost.cs @@ -17,6 +17,20 @@ namespace Avalonia.Controls /// event EventHandler ResourcesChanged; + /// + /// Begin batch updating resources hosted by this element. + /// + /// + /// After calling this method, will not be raised until + /// is called. + /// + void BeginBatchUpdate(); + + /// + /// End batch updating resources hosted by this element. + /// + void EndBatchUpdate(); + /// /// Notifies the resource host that one or more of its hosted resources has changed. /// diff --git a/src/Avalonia.Styling/StyledElement.cs b/src/Avalonia.Styling/StyledElement.cs index 65885ddebe..799c8a8e3a 100644 --- a/src/Avalonia.Styling/StyledElement.cs +++ b/src/Avalonia.Styling/StyledElement.cs @@ -67,6 +67,7 @@ namespace Avalonia private List? _appliedStyles; private ITemplatedControl? _templatedParent; private bool _dataContextUpdating; + private int _resourceBatchUpdate; /// /// Initializes static members of the class. @@ -371,6 +372,18 @@ namespace Avalonia /// void ILogical.NotifyResourcesChanged(ResourcesChangedEventArgs e) => NotifyResourcesChanged(e); + /// + void IResourceHost.BeginBatchUpdate() => ++_resourceBatchUpdate; + + /// + void IResourceHost.EndBatchUpdate() + { + if (_resourceBatchUpdate > 0 && --_resourceBatchUpdate == 0) + { + NotifyResourcesChanged(); + } + } + /// void IResourceHost.NotifyHostedResourcesChanged(ResourcesChangedEventArgs e) => NotifyResourcesChanged(e); @@ -799,6 +812,11 @@ namespace Avalonia ResourcesChangedEventArgs? e = null, bool propagate = true) { + if (_resourceBatchUpdate > 0) + { + return; + } + if (ResourcesChanged is object) { e ??= ResourcesChangedEventArgs.Empty;