diff --git a/README.md b/README.md
index d35f9a1..ff9a629 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ UpbeatUI implementations are available as NuGet packages:
Three samples are included: one showing [manual setup](samples/ManualUpbeatUISample) and teardown without dependency injection, one showing manual setup and teardown with [dependency injection](samples/ServiceProvidedUpbeatUISample) using an **IServiceProvider**, and one showing [automatic setup and teardown](samples/HostedUpbeatUISample) using an **IHostBuilder**. All samples demonstrate the following capabilities:
-![UpbeatUI Sample](https://user-images.githubusercontent.com/20475952/111044956-6c7e1200-8400-11eb-82f3-1befa64c951b.gif)
+![UpbeatUI Sample](https://github.com/Pulselyre/UpbeatUI/assets/20475952/968f2465-43cb-4486-a671-c8a0d898022e)
>Note: The background in the sample is OrangeRed to demonstrate how the effect can be configured. The default value is Gray.
diff --git a/samples/HostedUpbeatUISample/View/MenuControl.xaml b/samples/HostedUpbeatUISample/View/MenuControl.xaml
index 25340b8..17e3419 100644
--- a/samples/HostedUpbeatUISample/View/MenuControl.xaml
+++ b/samples/HostedUpbeatUISample/View/MenuControl.xaml
@@ -38,6 +38,15 @@
+
+
+
+
+
RaisePropertyChanged(nameof(Visibility))); // Registered "UpdateCallbacks" will be called each time the UI thread renders a new frame.
+
_sharedTimer.Ticked += SharedTimerTicked;
// DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
@@ -49,6 +54,7 @@ public MenuViewModel(
public ICommand OpenRandomDataCommand { get; }
public ICommand OpenSharedListCommand { get; }
public string SecondsElapsed => $"{_sharedTimer.ElapsedSeconds} Seconds";
+ public double Visibility => Math.Abs(1000.0 - _stopwatch.ElapsedMilliseconds % 2000) / 1000.0; // Will be calculated on each "RaisePropertyChanged(nameof(Visibility))" and used in the View to control visibility of an ellipse. Cycles between full and no visibility every two seconds.
public void Dispose() =>
_sharedTimer.Ticked -= SharedTimerTicked;
diff --git a/samples/ManualUpbeatUISample/View/MenuControl.xaml b/samples/ManualUpbeatUISample/View/MenuControl.xaml
index 9b8e520..535b923 100644
--- a/samples/ManualUpbeatUISample/View/MenuControl.xaml
+++ b/samples/ManualUpbeatUISample/View/MenuControl.xaml
@@ -38,6 +38,15 @@
+
+
+
+
+
RaisePropertyChanged(nameof(Visibility))); // Registered "UpdateCallbacks" will be called each time the UI thread renders a new frame.
+
_sharedTimer.Ticked += SharedTimerTicked;
// DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
@@ -49,6 +54,7 @@ public MenuViewModel(
public ICommand OpenRandomDataCommand { get; }
public ICommand OpenSharedListCommand { get; }
public string SecondsElapsed => $"{_sharedTimer.ElapsedSeconds} Seconds";
+ public double Visibility => Math.Abs(1000.0 - _stopwatch.ElapsedMilliseconds % 2000) / 1000.0; // Will be calculated on each "RaisePropertyChanged(nameof(Visibility))" and used in the View to control visibility of an ellipse. Cycles between full and no visibility every two seconds.
public void Dispose() =>
_sharedTimer.Ticked -= SharedTimerTicked;
diff --git a/samples/ServiceProvidedUpbeatUISample/View/MenuControl.xaml b/samples/ServiceProvidedUpbeatUISample/View/MenuControl.xaml
index 846f653..a1e19ac 100644
--- a/samples/ServiceProvidedUpbeatUISample/View/MenuControl.xaml
+++ b/samples/ServiceProvidedUpbeatUISample/View/MenuControl.xaml
@@ -38,6 +38,15 @@
+
+
+
+
+
RaisePropertyChanged(nameof(Visibility))); // Registered "UpdateCallbacks" will be called each time the UI thread renders a new frame.
+
_sharedTimer.Ticked += SharedTimerTicked;
// DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
@@ -49,6 +54,7 @@ public MenuViewModel(
public ICommand OpenRandomDataCommand { get; }
public ICommand OpenSharedListCommand { get; }
public string SecondsElapsed => $"{_sharedTimer.ElapsedSeconds} Seconds";
+ public double Visibility => Math.Abs(1000.0 - _stopwatch.ElapsedMilliseconds % 2000) / 1000.0; // Will be calculated on each "RaisePropertyChanged(nameof(Visibility))" and used in the View to control visibility of an ellipse. Cycles between full and no visibility every two seconds.
public void Dispose() =>
_sharedTimer.Ticked -= SharedTimerTicked;
diff --git a/source/UpbeatUI.Extensions.Hosting/HostedUpbeatService.cs b/source/UpbeatUI.Extensions.Hosting/HostedUpbeatService.cs
index 7ba14ad..c6862ee 100644
--- a/source/UpbeatUI.Extensions.Hosting/HostedUpbeatService.cs
+++ b/source/UpbeatUI.Extensions.Hosting/HostedUpbeatService.cs
@@ -8,6 +8,7 @@
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Extensions.Hosting;
+using UpbeatUI.Extensions.DependencyInjection;
namespace UpbeatUI.Extensions.Hosting
{
@@ -26,6 +27,7 @@ public Task StartAsync(CancellationToken cancellationToken)
{
Window mainWindow = null;
Task baseViewModelOpen = null;
+ _upbeatStack = new ServiceProvidedUpbeatStack(_serviceProvider ?? throw new ArgumentNullException(nameof(_serviceProvider)));
foreach (var registerer in _upbeatHostBuilder.MappingRegisterers ?? throw new InvalidOperationException($"No {nameof(_upbeatHostBuilder.MappingRegisterers)} provided."))
registerer.Invoke(_upbeatStack);
mainWindow = _upbeatHostBuilder.WindowCreator?.Invoke() ?? throw new InvalidOperationException($"No {nameof(_upbeatHostBuilder.WindowCreator)} provided.");
diff --git a/source/UpbeatUI.Extensions.Hosting/UpbeatApplicationService.cs b/source/UpbeatUI.Extensions.Hosting/UpbeatApplicationService.cs
index 60d53e7..91d1996 100644
--- a/source/UpbeatUI.Extensions.Hosting/UpbeatApplicationService.cs
+++ b/source/UpbeatUI.Extensions.Hosting/UpbeatApplicationService.cs
@@ -12,16 +12,17 @@ namespace UpbeatUI.Extensions.Hosting
internal class UpbeatApplicationService : IUpbeatApplicationService, IDisposable
{
protected readonly HostedUpbeatBuilder _upbeatHostBuilder;
- protected readonly ServiceProvidedUpbeatStack _upbeatStack;
protected readonly IHostApplicationLifetime _hostApplicationLifetime;
protected readonly TaskCompletionSource _applicationTaskSource = new TaskCompletionSource();
protected readonly TaskCompletionSource _forcedClosedTaskSource = new TaskCompletionSource();
+ protected readonly IServiceProvider _serviceProvider;
+ protected ServiceProvidedUpbeatStack _upbeatStack;
protected UpbeatApplicationService(HostedUpbeatBuilder upbeatHostBuilder, IServiceProvider serviceProvider, IHostApplicationLifetime hostApplicationLifetime)
{
_upbeatHostBuilder = upbeatHostBuilder ?? throw new ArgumentNullException(nameof(upbeatHostBuilder));
_hostApplicationLifetime = hostApplicationLifetime ?? throw new ArgumentNullException(nameof(hostApplicationLifetime));
- _upbeatStack = new ServiceProvidedUpbeatStack(serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)));
+ _serviceProvider = serviceProvider;
}
public async void CloseUpbeatApplication()