admin管理员组文章数量:1391937
I can't seem to solve this without using integers or different class or event names per button (which isn't scalable). I have a custom ripple-effect that I've created in Blazor and need each button on the page to receive a "ripple" class when clicked and then remove that class after a second or two.
@using System.Timers
<button class="primary-btn @buttonClass" @onclick="AddRipple">Action 1</button>
<button class="primary-btn @buttonClass" @onclick="AddRipple">Action 2</button>
@code {
// Set Ripple Class
private string buttonClass = "";
private void AddRipple()
{
buttonClass = "ripple";
StartTimer();
}
private void StartTimer()
{
var timer = new Timer(1000);
timer.Elapsed += RemoveClass;
timer.AutoReset = false;
timer.Start();
}
private void RemoveClass(object source, ElapsedEventArgs e)
{
buttonClass = "";
((Timer)source).Dispose();
InvokeAsync(StateHasChanged);
}
}
I have created and tested this functionality, but it applies the class change to every button on the page when any one button is clicked. How can I make the event fire and apply only the class change on the actual button clicked?
--UPDATE-- I created a custom razor component and that worked beautifully. I should have realized that! DOH! Here is a step by step guide if anyone is new at this like me:
I can't seem to solve this without using integers or different class or event names per button (which isn't scalable). I have a custom ripple-effect that I've created in Blazor and need each button on the page to receive a "ripple" class when clicked and then remove that class after a second or two.
@using System.Timers
<button class="primary-btn @buttonClass" @onclick="AddRipple">Action 1</button>
<button class="primary-btn @buttonClass" @onclick="AddRipple">Action 2</button>
@code {
// Set Ripple Class
private string buttonClass = "";
private void AddRipple()
{
buttonClass = "ripple";
StartTimer();
}
private void StartTimer()
{
var timer = new Timer(1000);
timer.Elapsed += RemoveClass;
timer.AutoReset = false;
timer.Start();
}
private void RemoveClass(object source, ElapsedEventArgs e)
{
buttonClass = "";
((Timer)source).Dispose();
InvokeAsync(StateHasChanged);
}
}
I have created and tested this functionality, but it applies the class change to every button on the page when any one button is clicked. How can I make the event fire and apply only the class change on the actual button clicked?
--UPDATE-- I created a custom razor component and that worked beautifully. I should have realized that! DOH! Here is a step by step guide if anyone is new at this like me: https://toxigon/building-reusable-components-in-blazor
Share Improve this question edited Mar 14 at 13:46 jottin asked Mar 14 at 0:59 jottinjottin 4312 silver badges13 bronze badges2 Answers
Reset to default 1Your thinking about this the wrong way. Build the functionality into a custom button component. Totally scalable.
Here's a demo MyButton
component that changes colour for 2 seconds. It uses the primitive System.Threading.Timer
to load a one time timer task onto the application timer. When this expires it calls OnTimerExpired
which renders the component. The component implements IDisposable
to clear down any running timers when the component is disposed.
@implements IDisposable
<button class="@_buttonClass" @onclick="AddRipple">@ChildContent</button>
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public EventCallback OnClick { get; set; }
private IDisposable? _disposer;
private bool _rippling;
private string _buttonClass => _rippling ? "btn btn-danger" : "btn btn-success";
private async Task AddRipple()
{
_rippling = true;
_disposer = new System.Threading.Timer(this.OnTimerExpired, null, TimeSpan.FromSeconds(2), TimeSpan.Zero);
await OnClick.InvokeAsync();
}
private void OnTimerExpired(object? data)
{
_rippling = false;
this.InvokeAsync(StateHasChanged);
}
public void Dispose()
{
_disposer?.Dispose();
}
}
See https://shauncurtis.github.io/Posts/Timers.html for more detailed info on timers.
From my understanding you need a list to control the state of each button class which uses independent timer.
@page "/"
<style>
.ripple{
color:red;
}
</style>
@using System.Timers
<button class="primary-btn @buttonClass[1]" @onclick="()=>AddRipple(1)">Action 1</button>
<button class="primary-btn @buttonClass[2]" @onclick="()=>AddRipple(2)">Action 2</button>
@code {
//create list of 3 items to match index 1 and 2.
private List<string> buttonClass = new List<string>(new string[3]);
private void AddRipple(int i)
{
buttonClass[i] = "ripple";
StartTimer(i);
}
private void StartTimer(int i)
{
var timer = new Timer(1000);
timer.Elapsed += (sender,e)=> RemoveClass(sender,e,i);
timer.AutoReset = false;
timer.Start();
}
private void RemoveClass(object source, ElapsedEventArgs e,int i)
{
buttonClass[i] = "";
((Timer)source).Dispose();
InvokeAsync(StateHasChanged);
}
}
本文标签:
版权声明:本文标题:asp.net core - Add Class When Button Is Clicked While Other Buttons Are Present On Page In Blazor - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744677760a2619215.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论