在 Blazor 服务器应用程序中,我有一个子组件,上面有一个按钮。子组件有一些来自父组件的数据绑定到(一个 Book 对象)。当我单击子组件上的此按钮时,我正在调用父组件中的单击事件处理程序。但是,父级中的此按钮诊所事件处理程序需要知道用户是否按下 Shift 键单击了子级上的按钮。我能够将数据对象(Book 对象)从子级传递到父级,但我无法弄清楚如何将 KeyEventArg 也从子级传递到父级,这将帮助父级知道 Shift 是否当用户单击子项上的按钮时,是否按下了键。我将不胜感激的帮助。 我包含了子组件和父组件的代码。
// 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
}
}
}
您可以创建一个简单的
struct
或 record
,但一次性情况下最简单的是 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;
//.....
}
这是我的演示代码:
成分:
<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 "/"
<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;
}
}
刚刚也遇到过类似的情况。我用一个解决方法解决了这个问题:创建一个标志变量。在@代码部分:
private bool ctrlKeyPressed = false;
private void ctrlKeyDown( KeyboardEventArgs ke)
{
if (ke.CtrlKey )
{
ctrlKeyPressed = true;
}
}
private void ctrlKeyUp(KeyboardEventArgs ke)
{
if (!ke.CtrlKey )
{
ctrlKeyPressed = false;
}
}
并在按钮元素上触发事件:
<button @onclick="doSomething" @onkeydown="ctrlKeyDown" @onkeyup"ctrlKeyUp">Click Me </button>
现在,doSomething 函数可以在 if 语句中使用标志变量 ctrlKeyPressed 。
希望有帮助