Add support for Action event handlers
This change adds `Action` to the set of types that have an overload on RenderTreeBuilder. Additionally, we special case `Action` in the runtime because passing the event args via DynamicInvoke() would throw. Finally, reverted some of the clutter introduced by the first pass of the event handler feature.
This commit is contained in:
parent
6d3838ef9d
commit
8485e2ea10
|
|
@ -1,5 +1,4 @@
|
|||
@page "/counter"
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
|
|
@ -10,7 +9,7 @@
|
|||
@functions {
|
||||
int currentCount = 0;
|
||||
|
||||
void IncrementCount(UIMouseEventArgs e)
|
||||
void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,15 @@ namespace Microsoft.AspNetCore.Blazor.Components
|
|||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not intended to be used directly.
|
||||
/// </summary>
|
||||
public static MulticastDelegate GetEventHandlerValue<T>(Action value)
|
||||
where T : UIEventArgs
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not intended to be used directly.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -148,6 +148,24 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Appends a frame representing an <see cref="Action"/>-valued attribute.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The attribute is associated with the most recently added element. If the value is <c>null</c> and the
|
||||
/// current element is not a component, the frame will be omitted.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="RenderTreeBuilder"/>.</param>
|
||||
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
|
||||
/// <param name="name">The name of the attribute.</param>
|
||||
/// <param name="value">The value of the attribute.</param>
|
||||
public void AddAttribute(int sequence, string name, Action value)
|
||||
{
|
||||
AddAttribute(sequence, name, (MulticastDelegate)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Appends a frame representing an <see cref="UIEventHandler"/>-valued attribute.
|
||||
|
|
|
|||
|
|
@ -125,15 +125,20 @@ namespace Microsoft.AspNetCore.Blazor.Rendering
|
|||
{
|
||||
_eventHandlersById.Add(id, wrapper);
|
||||
}
|
||||
// IMPORTANT: we're creating an additional delegate when necessary. This is
|
||||
// going to get cached in _eventHandlersById, but the render tree diff
|
||||
// will operate on 'AttributeValue' which means that we'll only create a new
|
||||
// wrapper delegate when the underlying delegate changes.
|
||||
//
|
||||
// TLDR: If the component uses a method group or a non-capturing lambda
|
||||
// we don't allocate much.
|
||||
else if (frame.AttributeValue is Action action)
|
||||
{
|
||||
_eventHandlersById.Add(id, (UIEventArgs e) => action());
|
||||
}
|
||||
else if (frame.AttributeValue is MulticastDelegate @delegate)
|
||||
{
|
||||
// IMPORTANT: we're creating an additional delegate when necessary. This is
|
||||
// going to get cached in _eventHandlersById, but the render tree diff
|
||||
// will operate on 'AttributeValue' which means that we'll only create a new
|
||||
// wrapper delegate when the underlying delegate changes.
|
||||
//
|
||||
// TLDR: If the component uses a method group or a non-capturing lambda
|
||||
// we don't allocate much.
|
||||
|
||||
_eventHandlersById.Add(id, (UIEventArgs e) => @delegate.DynamicInvoke(e));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Build.Test
|
||||
{
|
||||
|
|
@ -276,7 +275,23 @@ namespace Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void EventHandler_OnElement_WithLambdaDelegate()
|
||||
public void EventHandler_OnElement_WithNoArgsLambdaDelegate()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
var generated = CompileToCSharp(@"
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
<input onclick=""@(() => { })"" />");
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
|
||||
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
|
||||
CompileToAssembly(generated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EventHandler_OnElement_WithEventArgsLambdaDelegate()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
|
|
@ -292,7 +307,27 @@ namespace Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void EventHandler_OnElement_WithDelegate()
|
||||
public void EventHandler_OnElement_WithNoArgMethodGroup()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
var generated = CompileToCSharp(@"
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
<input onclick=""@OnClick"" />
|
||||
@functions {
|
||||
void OnClick() {
|
||||
}
|
||||
}");
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
|
||||
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
|
||||
CompileToAssembly(generated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EventHandler_OnElement_WithEventArgsMethodGroup()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
|
|
@ -310,5 +345,25 @@ namespace Test
|
|||
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
|
||||
CompileToAssembly(generated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EventHandler_OnElement_ArbitraryEventName_WithEventArgsMethodGroup()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
var generated = CompileToCSharp(@"
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
<input onclick=""@OnClick"" />
|
||||
@functions {
|
||||
void OnClick(UIEventArgs e) {
|
||||
}
|
||||
}");
|
||||
|
||||
// Assert
|
||||
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
|
||||
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
|
||||
CompileToAssembly(generated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Test
|
||||
{
|
||||
#line hidden
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Blazor;
|
||||
public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
base.BuildRenderTree(builder);
|
||||
builder.OpenElement(0, "input");
|
||||
builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(OnClick));
|
||||
builder.CloseElement();
|
||||
builder.AddContent(2, "\n");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
|
||||
|
||||
void OnClick(UIEventArgs e) {
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Document -
|
||||
NamespaceDeclaration - - Test
|
||||
UsingDirective - (3:1,1 [14] ) - System
|
||||
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
|
||||
UsingDirective - (53:3,1 [19] ) - System.Linq
|
||||
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
|
||||
UsingDirective - (1:0,1 [35] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
|
||||
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
|
||||
MethodDeclaration - - protected override - void - BuildRenderTree
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - <input
|
||||
HtmlAttribute - - =" - "
|
||||
CSharpExpressionAttributeValue - -
|
||||
IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(
|
||||
IntermediateToken - (53:1,17 [7] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - OnClick
|
||||
IntermediateToken - - CSharp - )
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - />
|
||||
HtmlContent - (64:1,28 [2] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
IntermediateToken - (64:1,28 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
|
||||
CSharpCode - (78:2,12 [44] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
IntermediateToken - (78:2,12 [44] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n void OnClick(UIEventArgs e) {\n }\n
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Source Location: (78:2,12 [44] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
|
|
||||
void OnClick(UIEventArgs e) {
|
||||
}
|
||||
|
|
||||
Generated Location: (964:23,12 [44] )
|
||||
|
|
||||
void OnClick(UIEventArgs e) {
|
||||
}
|
||||
|
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Test
|
||||
{
|
||||
#line hidden
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Blazor;
|
||||
public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
base.BuildRenderTree(builder);
|
||||
builder.OpenElement(0, "input");
|
||||
builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(x => { }));
|
||||
builder.CloseElement();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
Document -
|
||||
NamespaceDeclaration - - Test
|
||||
UsingDirective - (3:1,1 [14] ) - System
|
||||
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
|
||||
UsingDirective - (53:3,1 [19] ) - System.Linq
|
||||
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
|
||||
UsingDirective - (1:0,1 [35] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
|
||||
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
|
||||
MethodDeclaration - - protected override - void - BuildRenderTree
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - <input
|
||||
HtmlAttribute - - =" - "
|
||||
CSharpExpressionAttributeValue - -
|
||||
IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(
|
||||
IntermediateToken - (54:1,18 [8] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - x => { }
|
||||
IntermediateToken - - CSharp - )
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - />
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Test
|
||||
{
|
||||
#line hidden
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Blazor;
|
||||
public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
base.BuildRenderTree(builder);
|
||||
builder.OpenElement(0, "input");
|
||||
builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(OnClick));
|
||||
builder.CloseElement();
|
||||
builder.AddContent(2, "\n");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
|
||||
|
||||
void OnClick(UIMouseEventArgs e) {
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Document -
|
||||
NamespaceDeclaration - - Test
|
||||
UsingDirective - (3:1,1 [14] ) - System
|
||||
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
|
||||
UsingDirective - (53:3,1 [19] ) - System.Linq
|
||||
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
|
||||
UsingDirective - (1:0,1 [35] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
|
||||
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
|
||||
MethodDeclaration - - protected override - void - BuildRenderTree
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - <input
|
||||
HtmlAttribute - - =" - "
|
||||
CSharpExpressionAttributeValue - -
|
||||
IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(
|
||||
IntermediateToken - (53:1,17 [7] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - OnClick
|
||||
IntermediateToken - - CSharp - )
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - />
|
||||
HtmlContent - (64:1,28 [2] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
IntermediateToken - (64:1,28 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
|
||||
CSharpCode - (78:2,12 [49] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
IntermediateToken - (78:2,12 [49] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n void OnClick(UIMouseEventArgs e) {\n }\n
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Source Location: (78:2,12 [49] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
|
|
||||
void OnClick(UIMouseEventArgs e) {
|
||||
}
|
||||
|
|
||||
Generated Location: (964:23,12 [49] )
|
||||
|
|
||||
void OnClick(UIMouseEventArgs e) {
|
||||
}
|
||||
|
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Test
|
||||
{
|
||||
#line hidden
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Blazor;
|
||||
public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
base.BuildRenderTree(builder);
|
||||
builder.OpenElement(0, "input");
|
||||
builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(OnClick));
|
||||
builder.CloseElement();
|
||||
builder.AddContent(2, "\n");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
|
||||
|
||||
void OnClick() {
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Document -
|
||||
NamespaceDeclaration - - Test
|
||||
UsingDirective - (3:1,1 [14] ) - System
|
||||
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
|
||||
UsingDirective - (53:3,1 [19] ) - System.Linq
|
||||
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
|
||||
UsingDirective - (1:0,1 [35] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
|
||||
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
|
||||
MethodDeclaration - - protected override - void - BuildRenderTree
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - <input
|
||||
HtmlAttribute - - =" - "
|
||||
CSharpExpressionAttributeValue - -
|
||||
IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(
|
||||
IntermediateToken - (53:1,17 [7] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - OnClick
|
||||
IntermediateToken - - CSharp - )
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - />
|
||||
HtmlContent - (64:1,28 [2] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
IntermediateToken - (64:1,28 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
|
||||
CSharpCode - (78:2,12 [31] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
IntermediateToken - (78:2,12 [31] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n void OnClick() {\n }\n
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Source Location: (78:2,12 [31] x:\dir\subdir\Test\TestComponent.cshtml)
|
||||
|
|
||||
void OnClick() {
|
||||
}
|
||||
|
|
||||
Generated Location: (964:23,12 [31] )
|
||||
|
|
||||
void OnClick() {
|
||||
}
|
||||
|
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Test
|
||||
{
|
||||
#line hidden
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Blazor;
|
||||
public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
|
||||
{
|
||||
base.BuildRenderTree(builder);
|
||||
builder.OpenElement(0, "input");
|
||||
builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(() => { }));
|
||||
builder.CloseElement();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
Document -
|
||||
NamespaceDeclaration - - Test
|
||||
UsingDirective - (3:1,1 [14] ) - System
|
||||
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
|
||||
UsingDirective - (53:3,1 [19] ) - System.Linq
|
||||
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
|
||||
UsingDirective - (1:0,1 [35] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Blazor
|
||||
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
|
||||
MethodDeclaration - - protected override - void - BuildRenderTree
|
||||
CSharpCode -
|
||||
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - <input
|
||||
HtmlAttribute - - =" - "
|
||||
CSharpExpressionAttributeValue - -
|
||||
IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(
|
||||
IntermediateToken - (54:1,18 [9] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - () => { }
|
||||
IntermediateToken - - CSharp - )
|
||||
HtmlContent -
|
||||
IntermediateToken - - Html - />
|
||||
|
|
@ -498,7 +498,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_EventHandler_AddsFrame()
|
||||
public void AddAttribute_Element_UIEventHandler_AddsFrame()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
|
@ -518,7 +518,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_NullEventHandler_IgnoresFrame()
|
||||
public void AddAttribute_Element_NullUIEventHandler_IgnoresFrame()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
|
@ -534,6 +534,43 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
frame => AssertFrame.Element(frame, "elem", 1, 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_Action_AddsFrame()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
||||
var value = new Action(() => { });
|
||||
|
||||
// Act
|
||||
builder.OpenElement(0, "elem");
|
||||
builder.AddAttribute(1, "attr", value);
|
||||
builder.CloseElement();
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
builder.GetFrames(),
|
||||
frame => AssertFrame.Element(frame, "elem", 2, 0),
|
||||
frame => AssertFrame.Attribute(frame, "attr", value, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_NullAction_IgnoresFrame()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
||||
// Act
|
||||
builder.OpenElement(0, "elem");
|
||||
builder.AddAttribute(1, "attr", (Action)null);
|
||||
builder.CloseElement();
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
builder.GetFrames(),
|
||||
frame => AssertFrame.Element(frame, "elem", 1, 0));
|
||||
}
|
||||
|
||||
public static TheoryData<UIEventHandler> UIEventHandlerValues => new TheoryData<UIEventHandler>
|
||||
{
|
||||
null,
|
||||
|
|
@ -651,7 +688,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_ObjectEventHandler_AddsFrame()
|
||||
public void AddAttribute_Element_ObjectUIEventHandler_AddsFrame()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
|
@ -671,7 +708,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Component_ObjectEventHandleValue_SetsAttributeValue()
|
||||
public void AddAttribute_Component_ObjectUIEventHandleValue_SetsAttributeValue()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
|
@ -690,6 +727,46 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
frame => AssertFrame.Attribute(frame, "attr", value, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_ObjectAction_AddsFrame()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
||||
var value = new Action(() => { });
|
||||
|
||||
// Act
|
||||
builder.OpenElement(0, "elem");
|
||||
builder.AddAttribute(1, "attr", (object)value);
|
||||
builder.CloseElement();
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
builder.GetFrames(),
|
||||
frame => AssertFrame.Element(frame, "elem", 2, 0),
|
||||
frame => AssertFrame.Attribute(frame, "attr", value, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Component_ObjectAction_SetsAttributeValue()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new RenderTreeBuilder(new TestRenderer());
|
||||
|
||||
var value = new Action(() => { });
|
||||
|
||||
// Act
|
||||
builder.OpenComponent<TestComponent>(0);
|
||||
builder.AddAttribute(1, "attr", (object)value);
|
||||
builder.CloseComponent();
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
builder.GetFrames(),
|
||||
frame => AssertFrame.Component<TestComponent>(frame, 2, 0),
|
||||
frame => AssertFrame.Attribute(frame, "attr", value, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddAttribute_Element_ObjectNull_IgnoresFrame()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -217,6 +217,34 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
Assert.Same(eventArgs, receivedArgs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanDispatchActionEventsToTopLevelComponents()
|
||||
{
|
||||
// Arrange: Render a component with an event handler
|
||||
var renderer = new TestRenderer();
|
||||
object receivedArgs = null;
|
||||
|
||||
var component = new EventComponent
|
||||
{
|
||||
OnClickAction = () => { receivedArgs = new object(); }
|
||||
};
|
||||
var componentId = renderer.AssignComponentId(component);
|
||||
component.TriggerRender();
|
||||
|
||||
var eventHandlerId = renderer.Batches.Single()
|
||||
.ReferenceFrames
|
||||
.First(frame => frame.AttributeValue != null)
|
||||
.AttributeEventHandlerId;
|
||||
|
||||
// Assert: Event not yet fired
|
||||
Assert.Null(receivedArgs);
|
||||
|
||||
// Act/Assert: Event can be fired
|
||||
var eventArgs = new UIMouseEventArgs();
|
||||
renderer.DispatchEvent(componentId, eventHandlerId, eventArgs);
|
||||
Assert.NotNull(receivedArgs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanDispatchEventsToNestedComponents()
|
||||
{
|
||||
|
|
@ -955,6 +983,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
{
|
||||
public UIEventHandler OnTest { get; set; }
|
||||
public UIMouseEventHandler OnClick { get; set; }
|
||||
public Action OnClickAction { get; set; }
|
||||
|
||||
public bool SkipElement { get; set; }
|
||||
private int renderCount = 0;
|
||||
|
|
@ -974,11 +1003,15 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
{
|
||||
builder.AddAttribute(4, "onclick", OnClick);
|
||||
}
|
||||
if (OnClickAction != null)
|
||||
{
|
||||
builder.AddAttribute(5, "onclickaction", OnClickAction);
|
||||
}
|
||||
builder.CloseElement();
|
||||
builder.CloseElement();
|
||||
}
|
||||
builder.CloseElement();
|
||||
builder.AddContent(5, $"Render count: {++renderCount}");
|
||||
builder.AddContent(6, $"Render count: {++renderCount}");
|
||||
}
|
||||
|
||||
public void HandleEvent(UIEventHandler handler, UIEventArgs args)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
@using System.Collections.Generic
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
Child components follow.
|
||||
<button class="addChild" onclick="@AddChild">Add</button>
|
||||
<button class="removeChild" onclick="@RemoveChild">Remove</button>
|
||||
|
|
@ -13,13 +12,13 @@ Child components follow.
|
|||
int numAdded = 0;
|
||||
List<string> currentChildrenMessages = new List<string>();
|
||||
|
||||
void AddChild(UIMouseEventArgs e)
|
||||
void AddChild()
|
||||
{
|
||||
numAdded++;
|
||||
currentChildrenMessages.Add($"Child {numAdded}");
|
||||
}
|
||||
|
||||
void RemoveChild(UIMouseEventArgs e)
|
||||
void RemoveChild()
|
||||
{
|
||||
if (currentChildrenMessages.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
enum SelectableValue { First, Second, Third, Fourth }
|
||||
SelectableValue selectValue = SelectableValue.Second;
|
||||
|
||||
void AddAndSelectNewSelectOption(UIMouseEventArgs e)
|
||||
void AddAndSelectNewSelectOption()
|
||||
{
|
||||
includeFourthOption = true;
|
||||
selectValue = SelectableValue.Fourth;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
@using Microsoft.AspNetCore.Blazor
|
||||
<h1>Counter</h1>
|
||||
<h1>Counter</h1>
|
||||
<p>Current count: @currentCount</p>
|
||||
<p><button onclick="@((handleClicks ? (Action<UIMouseEventArgs>)IncrementCount : null))">Click me</button></p>
|
||||
<p><button onclick="@((handleClicks ? (Action)IncrementCount : null))">Click me</button></p>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" bind="@handleClicks" />
|
||||
|
|
@ -12,7 +11,7 @@
|
|||
int currentCount = 0;
|
||||
bool handleClicks = true;
|
||||
|
||||
void IncrementCount(UIMouseEventArgs e)
|
||||
void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
@using Microsoft.AspNetCore.Blazor
|
||||
<h1>Counter</h1>
|
||||
<h1>Counter</h1>
|
||||
|
||||
<!-- Note: passing 'Message' parameter with lowercase name to show it's case insensitive -->
|
||||
<p>Current count: <MessageComponent message=@currentCount.ToString() /></p>
|
||||
|
|
@ -9,7 +8,7 @@
|
|||
@functions {
|
||||
int currentCount = 0;
|
||||
|
||||
void IncrementCount(UIMouseEventArgs e)
|
||||
void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
@addTagHelper *, TestContentPackage
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
@using TestContentPackage
|
||||
|
||||
<h1>Functionality and content from an external package</h1>
|
||||
|
|
@ -32,7 +31,7 @@
|
|||
{
|
||||
string result;
|
||||
|
||||
void ShowJavaScriptPrompt(UIMouseEventArgs e)
|
||||
void ShowJavaScriptPrompt()
|
||||
{
|
||||
result = MyPrompt.Show("Hello!");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
@using Microsoft.AspNetCore.Blazor
|
||||
@inject System.Net.Http.HttpClient Http
|
||||
@inject System.Net.Http.HttpClient Http
|
||||
|
||||
<h1>Cookie counter</h1>
|
||||
<p>The server increments the count by one on each request.</p>
|
||||
|
|
@ -18,13 +17,13 @@
|
|||
string testServerBaseUrl;
|
||||
string responseText;
|
||||
|
||||
async void DeleteCookie(UIMouseEventArgs e)
|
||||
async void DeleteCookie()
|
||||
{
|
||||
await DoRequest("api/cookie/reset");
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
async void GetAndIncrementCounter(UIMouseEventArgs e)
|
||||
async void GetAndIncrementCounter()
|
||||
{
|
||||
await DoRequest("api/cookie/increment");
|
||||
StateHasChanged();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
@using System.Net
|
||||
@using System.Net.Http
|
||||
@using Microsoft.AspNetCore.Blazor
|
||||
@using Microsoft.AspNetCore.Blazor.Browser.Http
|
||||
@inject HttpClient Http
|
||||
|
||||
|
|
@ -72,7 +71,7 @@
|
|||
string responseBody;
|
||||
string responseHeaders;
|
||||
|
||||
async void DoRequest(UIMouseEventArgs e)
|
||||
async void DoRequest()
|
||||
{
|
||||
responseStatusCode = null;
|
||||
|
||||
|
|
@ -125,7 +124,7 @@
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
void AddHeader(UIMouseEventArgs e)
|
||||
void AddHeader()
|
||||
=> requestHeaders.Add(new RequestHeader());
|
||||
|
||||
void RemoveHeader(RequestHeader header)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
@using Microsoft.AspNetCore.Blazor
|
||||
<div class="special-style">
|
||||
<div class="special-style">
|
||||
This component, including the CSS and image required to produce its
|
||||
elegant styling, is in an external NuGet package.
|
||||
<button onclick="@ChangeLabel">@buttonLabel </button>
|
||||
|
|
@ -8,7 +7,7 @@
|
|||
@functions {
|
||||
string buttonLabel = "Click me";
|
||||
|
||||
void ChangeLabel(UIMouseEventArgs e)
|
||||
void ChangeLabel()
|
||||
{
|
||||
buttonLabel = "It works";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue