Reputation: 99
In Blazor Server App I have a Child Component which has a button on it. The Child Componet has some data from the parent bound to (a Book objec). I am calling a click event handler in the parent when I click this button on the Child Component. However, this button clinic event Handler in the parent needs to know wheter the user clicked the button on the chid with Shift Key Pressed or not. I am able to pass the data object (a Book object) from the Child to the parent, but I have not been able to figure out how I pass KeyEventArg also from the Child to the parent, which will help the parent know whether the Shift Key was pressed or not when the user clicked on a button on the child. I would appreciate help. I include code for my Child Component and Parent Component.
// Code for the Child
<div class="card-faheem">
<div >
<span class="span-fa">@BookContainer.ValueWord</span>
</div>
<div class="button-div">
<button class="btn btn-primary" title="View" @onclick="@(async () => await OnSelected.InvokeAsync(BookContainer))">
<i class="bi bi-binoculars"></i>
</button>
</div>
</div>
@code
{
[Parameter, EditorRequired] public TextContainer BookContainer { get; set; } = default!;
[Parameter, EditorRequired] public EventCallback<TextContainer> OnSelected { get; set; }
}
// Code for the parent
@inject TextContainerRepository tcr
<h3>CardParentPage</h3>
<div >
@foreach (var book in books)
{
<CardComponent BookContainer=book OnSelected="HandleSelectedBook" />
}
</div>
@code {
List<TextContainer> books { get; set; }
protected override async Task OnInitializedAsync()
{
books = tcr.GetBooksByAuthorName("Jane Auston");
}
private void HandleSelectedBook(TextContainer book)
{
if (true)
// (args.ShiftKey)
{
// Do something if ShifKey was pressed
} else
{
// Do something else if ShifKey was no pressed
}
}
}
Upvotes: 0
Views: 311
Reputation: 1
Just had a similar situation. I solved it with a workaround: create a flag variable. In the @code section:
private bool ctrlKeyPressed = false;
private void ctrlKeyDown( KeyboardEventArgs ke)
{
if (ke.CtrlKey )
{
ctrlKeyPressed = true;
}
}
private void ctrlKeyUp(KeyboardEventArgs ke)
{
if (!ke.CtrlKey )
{
ctrlKeyPressed = false;
}
}
And on the button element fired the event:
<button @onclick="doSomething" @onkeydown="ctrlKeyDown" @onkeyup"ctrlKeyUp">Click Me </button>
So now, the doSomething function can use the flag variable ctrlKeyPressed in an if statement.
Hope it helps
Upvotes: 0
Reputation: 30036
You can create a simple struct
or record
, but the simplest in one off situations is the Tuple
.
[Parameter, EditorRequired] public EventCallback<Tuple<MouseEventArgs,TextContainer>> OnSelected { get; set; }
<button class="btn btn-primary" title="View" @onclick="(e) => Selected(e, BookContainer)">
//....
private async Task Selected(MouseEventArgs e, TextContainer book)
=> await OnSelected.InvokeAsync(new Tuple<MouseEventArgs, TextContainer>(e, book));
private void HandleSelectedBook(Tuple<MouseEventArgs,TextContainer> data)
{
var x = data.Item1.AltKey;
//.....
}
Here's my demo code:
Component:
<h3>BookComponent</h3>
<button class="btn btn-success" @onclick="@((e) => OnSelected(e, "Mansfield Park"))">Select Pride and Passion</button>
@code {
[Parameter] public EventCallback<Tuple<MouseEventArgs, string>> BookSelected { get; set; }
private async Task OnSelected(MouseEventArgs e, string book)
=> await BookSelected.InvokeAsync(new Tuple<MouseEventArgs, string>(e, book));
}
Page:
@page "/"
<PageTitle>Index</PageTitle>
<BookComponent BookSelected=OnBookSelected />
<div class="alert alert-info">
@message
</div>
@code {
private string message = "Not Set";
private Task OnBookSelected(Tuple<MouseEventArgs,string> data)
{
message = data.Item1.ShiftKey ? $"Shifted {data.Item2}" : $"{data.Item2}";
return Task.CompletedTask;
}
}
Upvotes: 2