You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
7.2 KiB
251 lines
7.2 KiB
![]()
2 years ago
|
---
|
||
|
sidebar_position: 5
|
||
|
title: Component subcomponent
|
||
|
---
|
||
|
|
||
|
Our component will mainly call for an item, whether to fill the grid, display the boxes of the recipe and even the result.
|
||
|
|
||
|
In order not to have to repeat code in our component, we will therefore create a sub-component which will allow the display of our elements.
|
||
|
|
||
|
Our component remains simple but uses the Drag & Drop method.
|
||
|
|
||
|
## Creating our base component view
|
||
|
|
||
|
```cshtml title="Components/CraftingItem.razor"
|
||
|
<div
|
||
|
class="item"
|
||
|
ondragover="event.preventDefault();"
|
||
|
draggable="true"
|
||
|
@ondragstart="@OnDragStart"
|
||
|
@ondrop="@OnDrop"
|
||
|
@ondragenter="@OnDragEnter"
|
||
|
@ondragleave="@OnDragLeave">
|
||
|
|
||
|
@if (Item != null)
|
||
|
{
|
||
|
@Item.DisplayName
|
||
|
}
|
||
|
</div>
|
||
|
```
|
||
|
|
||
|
We use Razor's envent handling for Drag & Drop methods.
|
||
|
|
||
|
## Creating our component code
|
||
|
|
||
|
The code of our item remains simple, we call on our parent in order to pass it the action information as well as Drag & Drop.
|
||
|
|
||
|
```csharp title="Components/CraftingItem.razor.cs"
|
||
|
public partial class CraftingItem
|
||
|
{
|
||
|
[Parameter]
|
||
|
public int Index { get; set; }
|
||
|
|
||
|
[Parameter]
|
||
|
public Item Item { get; set; }
|
||
|
|
||
|
[Parameter]
|
||
|
public bool NoDrop { get; set; }
|
||
|
|
||
|
[CascadingParameter]
|
||
|
public Crafting Parent { get; set; }
|
||
|
|
||
|
internal void OnDragEnter()
|
||
|
{
|
||
|
if (NoDrop)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Parent.Actions.Add(new CraftingAction { Action = "Drag Enter", Item = this.Item, Index = this.Index });
|
||
|
}
|
||
|
|
||
|
internal void OnDragLeave()
|
||
|
{
|
||
|
if (NoDrop)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Parent.Actions.Add(new CraftingAction { Action = "Drag Leave", Item = this.Item, Index = this.Index });
|
||
|
}
|
||
|
|
||
|
internal void OnDrop()
|
||
|
{
|
||
|
if (NoDrop)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.Item = Parent.CurrentDragItem;
|
||
|
Parent.RecipeItems[this.Index] = this.Item;
|
||
|
|
||
|
Parent.Actions.Add(new CraftingAction { Action = "Drop", Item = this.Item, Index = this.Index });
|
||
|
|
||
|
// Check recipe
|
||
|
Parent.CheckRecipe();
|
||
|
}
|
||
|
|
||
|
private void OnDragStart()
|
||
|
{
|
||
|
Parent.CurrentDragItem = this.Item;
|
||
|
|
||
|
Parent.Actions.Add(new CraftingAction { Action = "Drag Start", Item = this.Item, Index = this.Index });
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
It is also possible to create CSS style files directly for our component, this file will be automatically rendered with our component.
|
||
|
|
||
|
```css title="Components/CraftingItem.razor.cs"
|
||
|
.item {
|
||
|
width: 64px;
|
||
|
height: 64px;
|
||
|
border: 1px solid;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Concept: Event handling
|
||
|
|
||
|
Specify delegate event handlers in Razor component markup with `@on{DOM EVENT}="{DELEGATE}"` Razor syntax:
|
||
|
* The `{DOM EVENT}` placeholder is a Document Object Model (DOM) event (for example, `click`).
|
||
|
* The `{DELEGATE}` placeholder is the C# delegate event handler.
|
||
|
|
||
|
For event handling:
|
||
|
* Asynchronous delegate event handlers that return a Task are supported.
|
||
|
* Delegate event handlers automatically trigger a UI render, so there's no need to manually call StateHasChanged.
|
||
|
* Exceptions are logged.
|
||
|
|
||
|
The following code:
|
||
|
* Calls the `UpdateHeading` method when the button is selected in the UI.
|
||
|
* Calls the `CheckChanged` method when the checkbox is changed in the UI.
|
||
|
|
||
|
```cshtml title="Pages/EventHandlerExample1.razor"
|
||
|
@page "/event-handler-example-1"
|
||
|
|
||
|
<h1>@currentHeading</h1>
|
||
|
|
||
|
<p>
|
||
|
<label>
|
||
|
New title
|
||
|
<input @bind="newHeading" />
|
||
|
</label>
|
||
|
// highlight-next-line
|
||
|
Update heading
|
||
|
</button>
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
<label>
|
||
|
// highlight-next-line
|
||
|
<input type="checkbox" @onchange="CheckChanged" />
|
||
|
@checkedMessage
|
||
|
</label>
|
||
|
</p>
|
||
|
|
||
|
@code {
|
||
|
private string currentHeading = "Initial heading";
|
||
|
private string? newHeading;
|
||
|
private string checkedMessage = "Not changed yet";
|
||
|
|
||
|
// highlight-start
|
||
|
private void UpdateHeading()
|
||
|
{
|
||
|
currentHeading = $"{newHeading}!!!";
|
||
|
}
|
||
|
|
||
|
private void CheckChanged()
|
||
|
{
|
||
|
checkedMessage = $"Last changed at {DateTime.Now}";
|
||
|
}
|
||
|
// highlight-end
|
||
|
}
|
||
|
```
|
||
|
|
||
|
In the following example, `UpdateHeading`:
|
||
|
* Is called asynchronously when the button is selected.
|
||
|
* Waits two seconds before updating the heading.
|
||
|
|
||
|
```cshtml title="Pages/EventHandlerExample2.razor"
|
||
|
@page "/event-handler-example-2"
|
||
|
|
||
|
<h1>@currentHeading</h1>
|
||
|
|
||
|
<p>
|
||
|
<label>
|
||
|
New title
|
||
|
<input @bind="newHeading" />
|
||
|
</label>
|
||
|
// highlight-next-line
|
||
|
<button @onclick="UpdateHeading">
|
||
|
Update heading
|
||
|
</button>
|
||
|
</p>
|
||
|
|
||
|
@code {
|
||
|
private string currentHeading = "Initial heading";
|
||
|
private string? newHeading;
|
||
|
|
||
|
// highlight-start
|
||
|
private async Task UpdateHeading()
|
||
|
{
|
||
|
await Task.Delay(2000);
|
||
|
|
||
|
currentHeading = $"{newHeading}!!!";
|
||
|
}
|
||
|
// highlight-end
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Event arguments
|
||
|
|
||
|
For events that support an event argument type, specifying an event parameter in the event method definition is only necessary if the event type is used in the method.
|
||
|
|
||
|
In the following example, `MouseEventArgs` is used in the `ReportPointerLocation` method to set message text that reports the mouse coordinates when the user selects a button in the UI.
|
||
|
|
||
|
```cshtml title="Pages/EventHandlerExample3.razor"
|
||
|
@page "/event-handler-example-3"
|
||
|
|
||
|
@for (var i = 0; i < 4; i++)
|
||
|
{
|
||
|
<p>
|
||
|
<button @onclick="ReportPointerLocation">
|
||
|
Where's my mouse pointer for this button?
|
||
|
</button>
|
||
|
</p>
|
||
|
}
|
||
|
|
||
|
<p>@mousePointerMessage</p>
|
||
|
|
||
|
@code {
|
||
|
private string? mousePointerMessage;
|
||
|
|
||
|
// highlight-start
|
||
|
private void ReportPointerLocation(MouseEventArgs e)
|
||
|
{
|
||
|
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
|
||
|
}
|
||
|
// highlight-end
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Supported EventArgs
|
||
|
|
||
|
| Event | Class | Document Object Model (DOM) events |
|
||
|
| ---- | ---- | ---- |
|
||
|
| Clipboard | ClipboardEventArgs | `oncut`, `oncopy`, `onpaste` |
|
||
|
| Drag | DragEventArgs | `ondrag`, `ondragstart`, `ondragenter`, `ondragleave`, `ondragover`, `ondrop`, `ondragend` |
|
||
|
| Error | ErrorEventArgs | `onerror` |
|
||
|
| General | EventArgs | `onactivate`, `onbeforeactivate`, `onbeforedeactivate`, `ondeactivate`, `onfullscreenchange`, `onfullscreenerror`, `onloadeddata`, `onloadedmetadata`, `onpointerlockchange`, `onpointerlockerror`, `onreadystatechange`, `onscroll` |
|
||
|
| Clipboard | EventArgs | `onbeforecut`, `onbeforecopy`, `onbeforepaste` |
|
||
|
| Input | EventArgs | `oninvalid`, `onreset`, `onselect`, `onselectionchange`, `onselectstart`, `onsubmit` |
|
||
|
| Media | EventArgs | `oncanplay`, `oncanplaythrough`, `oncuechange`, `ondurationchange`, `onemptied`, `onended`, `onpause`, `onplay`, `onplaying`, `onratechange`, `onseeked`, `onseeking`, `onstalled`, `onstop`, `onsuspend`, `ontimeupdate`, `ontoggle`, `onvolumechange`, `onwaiting` |
|
||
|
| Focus | FocusEventArgs | `onfocus`, `onblur`, `onfocusin`, `onfocusout` |
|
||
|
| Input | ChangeEventArgs | `onchange`, `oninput` |
|
||
|
| Keyboard | KeyboardEventArgs | `onkeydown`, `onkeypress`, `onkeyup` |
|
||
|
| Mouse | MouseEventArgs | `onclick`, `oncontextmenu`, `ondblclick`, `onmousedown`, `onmouseup`, `onmouseover`, `onmousemove`, `onmouseout` |
|
||
|
| Mouse pointer | PointerEventArgs | `onpointerdown`, `onpointerup`, `onpointercancel`, `onpointermove`, `onpointerover`, `onpointerout`, `onpointerenter`, `onpointerleave`, `ongotpointercapture`, `onlostpointercapture` |
|
||
|
| Mouse wheel | WheelEventArgs | `onwheel`, `onmousewheel` |
|
||
|
| Progress | ProgressEventArgs | `onabort`, `onload`, `onloadend`, `onloadstart`, `onprogress`, `ontimeout` |
|
||
|
| Touch | TouchEventArgs | `ontouchstart`, `ontouchend`, `ontouchmove`, `ontouchenter`, `ontouchleave`, `ontouchcancel` |
|