Links
Basic component
Components/MyComponent.razor
|
<h1>Test</h1>
<p>@ChildContent</p>
|
Components/MyComponent.razor.cs
|
public partial class MyComponent : ComponentBase
{
[Parameter]
public RenderFragment ChildContent { get; set; }
}
|
Components/MyComponent.razor.css
|
h1 {
color: coral;
}
|
Pages/Index.razor
|
@page "/"
@using Component.Components
<MyComponent>
test !!!
</MyComponent>
|
Components/MyComponent.razor.cs
|
[Parameter]
public EventCallback<string> Callback { get; set; }
private string description;
private async Task UpdateDescription()
{
await Callback.InvokeAsync(description);
}
|
Pages/Index.razor
|
<MyComponent Callback="MyComponentCallback" />
@code {
void MyComponentCallback(string description)
{
}
}
|
Components/MyComponent.razor.cs
|
[Parameter]
public string Description { get; set; }
// name of the EventCallback has to be [PropertyName]Changed
[Parameter]
public EventCallback<string> DescriptionChanged { get; set; }
private async Task UpdateDescription()
{
await DescriptionChanged.InvokeAsync(description);
}
|
Pages/Index.razor
|
@* two ways binding of the component parameter Description with the local field description *@
<MyComponent @bind-Description="description" />
@code {
private string description = "Text";
}
|
Set a value for the component hierarchy from an ancestor component to any number of descendent components.
Pages/Index.razor
|
@* BtnStyle will be available in MyComponent and all its descendent components *@
<CascadingValue Value="btnStyle" IsFixed="true">
<MyComponent />
</CascadingValue>
@code {
string btnStyle = "btn-success";
}
|
Components/MyComponent.razor.cs
|
// match between the cascading value and the cascading parameter is made by the type (string) and not by the property name
[CascadingParameter]
public string BtnStyle { get; set; }
|
If the IsFixed value is true (false by default), then receipients receive the initial value but do not set up any subscription to receive updates. In this case, each [CascadingParameter] is lightweight and no more expensive than a regular [Parameter].
So wherever possible, you should use IsFixed="true" on cascaded values. You can do this whenever the value being supplied doesn't change over time.
Component references provide a way to reference a component instance for issuing commands.
Pages/Index.razor
|
<MyComponent @ref="myComponent" />
<button @onclick="@(() => myComponent.MyMethod())">
Call <code>MyComponent.MyMethod</code>
</button>
@code {
private MyComponent myComponent;
}
|
Instead of having multiple parameters, have one parameter of type dictionary to pass multiple attributes.
Components/MyComponent.razor.cs
|
[Parameter(CaptureUnmatchedValues = true)]
public IReadOnlyDictionary<string, object> AdditionalAttributes { get; set; }
protected string CssClass
{
get
{
var cssClass = string.Empty;
if (AdditionalAttributes != null &&
AdditionalAttributes.TryGetValue("class", out var @class))
{
cssClass = Convert.ToString(@class, CultureInfo.InvariantCulture);
}
return cssClass;
}
}
|
Pages/Index.razor
|
<MyComponent class="class"></MyComponent>
|
Custom components
Input text with clear button
InputTextClear.razor
|
@inherits InputBase<string>
<input @attributes="AdditionalAttributes" class="@CssClass" @bind="CurrentValueAsString" @bind:event="@BindEvent" @ref="Element" />
<span class="oi oi-x" @onclick="Clear"></span>
|
InputTextClear.razor.cs
|
public partial class InputTextClear3 : InputBase<string>
{
public ElementReference Element { get; private set; }
protected string BindEvent
{
get
{
var bindEvent = "onchange";
if (AdditionalAttributes != null &&
AdditionalAttributes.TryGetValue("bind-event", out var bindEventAttribute))
{
var bindEventAttributeAsString = Convert.ToString(bindEventAttribute, CultureInfo.InvariantCulture);
if (bindEventAttributeAsString == "onchange" || bindEventAttributeAsString == "oninput")
{
bindEvent = bindEventAttributeAsString;
}
}
return bindEvent;
}
}
protected override bool TryParseValueFromString(
string value,
out string result,
out string validationErrorMessage)
{
result = value;
validationErrorMessage = null;
return true;
}
private async Task Clear()
{
CurrentValue = string.Empty;
await Element.FocusAsync();
}
}
|
InputTextClear.razor.css
|
input {
margin-right: -1.5rem;
padding-right: 1.5rem;
}
|
|
<InputTextClear @bind-Value="input" bind-event="oninput" id="id" class="class"></InputTextClear3>
|