我如何在 Blazor 中创建计时器组件并从组件或其他页面外部启动它
How I can Create a timer component in Blazor and start it from outside of component or other page
如何在 Blazor 中创建计时器组件并从组件外部或其他页面启动它。
我的组件代码如下:
@using LosacoWeb.Shared.Enumes
@using System.Timers
@implements IDisposable
@if (BlnVisiblaState == true)
{
<section>
<div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<div>
<div class="alert shortcode_modules" style="border-color:lightblue;border-style: solid;border-width: thin;padding: 5px;margin: 5px 10px;border-radius: 5px;" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>
<div class="modules__title">
<h3 dir="rtl" style="float:right;">@MessageTitle</h3>
</div>
<div class="modules__content">
@if (message == MessagePanelColor.primary)
{
<div class="alert alert-primary" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.secondary)
{
<div class="alert alert-secondary" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.success)
{
<div class="alert alert-success" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.info)
{
<div class="alert alert-info" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.warning)
{
<div class="alert alert-warning" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.danger)
{
<div class="alert alert-danger" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
</div>
</div>
</div>
<!-- end .col-md-6 -->
</div>
<!-- end .row -->
</div>
<!-- end .container -->
</div>
</section>
}
@code
{
[Parameter]
public Boolean BlnVisiblaState { get; set; }
[Parameter]
public String MessageTitle { get; set; }
[Parameter]
public String MessageShortDescription { get; set; }
[Parameter]
public String MessageBuddyLongDescription { get; set; }
[Parameter]
public LosacoWeb.Shared.Enumes.MessagePanelColor message { get; set; }
Timer timer;
int int_Counter = 0;
public async Task ChangeState()
{
BlnVisiblaState = !BlnVisiblaState;
timer.Stop();
}
protected override void OnInitialized()
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.Start();
}
public async Task StasrtTimer()
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.Start();
}
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (int_Counter >= 5)
{
ChangeState();
//Console.WriteLine(DateTime.Now.Ticks.ToString());
StateHasChanged();
}
int_Counter++;
Console.WriteLine(int_Counter.ToString());
}
public void Dispose()
{
if (timer != null)
{
timer.Dispose();
}
}
}
但我不知道如何从其他 Blazor 页面启动和停止计时器。此页面应显示按摩,并在 6 秒后隐藏。但我无法从外部页面启动计时器。感谢您的关注。
您实际上并没有像问题标题中的 post 那样创建计时器组件。
您真正想要的是创建一个服务 class,您可以将其注入到您的组件中。您可以通过多种方式做到这一点,并提供您想要的任何功能。
您的定时器服务 class 可能看起来像这样 (Warning you should also implement the IDisposable interface to dispose the timer in order to prevent memory leaks
):
using System.Threading.Tasks;
using System.Timers;
public class BlazorTimer
{
private Timer _timer;
private int count;
private int end;
internal void SetTimer(double interval, int start, int _end)
{
_timer = new Timer(interval);
_timer.Elapsed += Counter;
_timer.Enabled = true;
count = start;
end = _end;
_timer.Start();
}
private void Counter(object sender, ElapsedEventArgs e)
{
count++;
if (count >= end)
{
((Timer)sender).Stop();
TimerEventArgs args = new TimerEventArgs { Count = count };
OnCountCompleted(args);
}
}
protected virtual void OnCountCompleted(TimerEventArgs args)
{
EventHandler<TimerEventArgs> handler = CountCompleted;
if (handler != null)
{
handler(this, args);
}
}
public event EventHandler<TimerEventArgs> CountCompleted;
}
public class TimerEventArgs : EventArgs
{
public int Count { get; set; }
}
Program.cs
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
//...Code removed for brevity's sake...
builder.Services.AddScoped(config =>
{
var blazorTimer = new BlazorTimer();
blazorTimer.SetTimer(1000, 100, 110);
return blazorTimer;
});
await builder.Build().RunAsync();
}
}
用法
@page "/counter"
@inject BlazorTimer Timer
@implements IDisposable
<h1>Counter</h1>
@count.ToString()
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
protected override void OnInitialized()
{
Timer.CountCompleted += NotifyCompleted;
base.OnInitialized();
}
int count = 0;
private void NotifyCompleted(object sender, TimerEventArgs args)
{
count = args.Count;
InvokeAsync(() => { StateHasChanged(); });
}
public void Dispose()
{
Timer.CountCompleted -= NotifyCompleted;
}
}
注意:正如我之前所说,您可以通过多种方式进行编码,例如,您不必在注入 Timer 时设置间隔、开始和结束的值(Main 方法),您可以对其进行编码以从 OnInitialised(Async) 方法对中的组件获取这些值。
如何在 Blazor 中创建计时器组件并从组件外部或其他页面启动它。 我的组件代码如下:
@using LosacoWeb.Shared.Enumes
@using System.Timers
@implements IDisposable
@if (BlnVisiblaState == true)
{
<section>
<div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<div>
<div class="alert shortcode_modules" style="border-color:lightblue;border-style: solid;border-width: thin;padding: 5px;margin: 5px 10px;border-radius: 5px;" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>
<div class="modules__title">
<h3 dir="rtl" style="float:right;">@MessageTitle</h3>
</div>
<div class="modules__content">
@if (message == MessagePanelColor.primary)
{
<div class="alert alert-primary" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.secondary)
{
<div class="alert alert-secondary" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.success)
{
<div class="alert alert-success" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.info)
{
<div class="alert alert-info" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.warning)
{
<div class="alert alert-warning" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
@if (message == MessagePanelColor.danger)
{
<div class="alert alert-danger" role="alert">
<strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
@*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span class="icon-close" aria-hidden="true"></span>
</button>*@
</div>
}
</div>
</div>
</div>
<!-- end .col-md-6 -->
</div>
<!-- end .row -->
</div>
<!-- end .container -->
</div>
</section>
}
@code
{
[Parameter]
public Boolean BlnVisiblaState { get; set; }
[Parameter]
public String MessageTitle { get; set; }
[Parameter]
public String MessageShortDescription { get; set; }
[Parameter]
public String MessageBuddyLongDescription { get; set; }
[Parameter]
public LosacoWeb.Shared.Enumes.MessagePanelColor message { get; set; }
Timer timer;
int int_Counter = 0;
public async Task ChangeState()
{
BlnVisiblaState = !BlnVisiblaState;
timer.Stop();
}
protected override void OnInitialized()
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.Start();
}
public async Task StasrtTimer()
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.Start();
}
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (int_Counter >= 5)
{
ChangeState();
//Console.WriteLine(DateTime.Now.Ticks.ToString());
StateHasChanged();
}
int_Counter++;
Console.WriteLine(int_Counter.ToString());
}
public void Dispose()
{
if (timer != null)
{
timer.Dispose();
}
}
}
但我不知道如何从其他 Blazor 页面启动和停止计时器。此页面应显示按摩,并在 6 秒后隐藏。但我无法从外部页面启动计时器。感谢您的关注。
您实际上并没有像问题标题中的 post 那样创建计时器组件。 您真正想要的是创建一个服务 class,您可以将其注入到您的组件中。您可以通过多种方式做到这一点,并提供您想要的任何功能。
您的定时器服务 class 可能看起来像这样 (Warning you should also implement the IDisposable interface to dispose the timer in order to prevent memory leaks
):
using System.Threading.Tasks;
using System.Timers;
public class BlazorTimer
{
private Timer _timer;
private int count;
private int end;
internal void SetTimer(double interval, int start, int _end)
{
_timer = new Timer(interval);
_timer.Elapsed += Counter;
_timer.Enabled = true;
count = start;
end = _end;
_timer.Start();
}
private void Counter(object sender, ElapsedEventArgs e)
{
count++;
if (count >= end)
{
((Timer)sender).Stop();
TimerEventArgs args = new TimerEventArgs { Count = count };
OnCountCompleted(args);
}
}
protected virtual void OnCountCompleted(TimerEventArgs args)
{
EventHandler<TimerEventArgs> handler = CountCompleted;
if (handler != null)
{
handler(this, args);
}
}
public event EventHandler<TimerEventArgs> CountCompleted;
}
public class TimerEventArgs : EventArgs
{
public int Count { get; set; }
}
Program.cs
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
//...Code removed for brevity's sake...
builder.Services.AddScoped(config =>
{
var blazorTimer = new BlazorTimer();
blazorTimer.SetTimer(1000, 100, 110);
return blazorTimer;
});
await builder.Build().RunAsync();
}
}
用法
@page "/counter"
@inject BlazorTimer Timer
@implements IDisposable
<h1>Counter</h1>
@count.ToString()
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
protected override void OnInitialized()
{
Timer.CountCompleted += NotifyCompleted;
base.OnInitialized();
}
int count = 0;
private void NotifyCompleted(object sender, TimerEventArgs args)
{
count = args.Count;
InvokeAsync(() => { StateHasChanged(); });
}
public void Dispose()
{
Timer.CountCompleted -= NotifyCompleted;
}
}
注意:正如我之前所说,您可以通过多种方式进行编码,例如,您不必在注入 Timer 时设置间隔、开始和结束的值(Main 方法),您可以对其进行编码以从 OnInitialised(Async) 方法对中的组件获取这些值。