Blazor API review changes: CompilerServices (#11911)

* Blazor API review changes: CompilerServices

Fixes: #11907

These are the changes from the compiler-related API review that are safe
to make (these methods are not used).

I'll follow up with `BindMethods.GetValue` separately because that's
used by the compiler.
This commit is contained in:
Ryan Nowak 2019-07-08 20:01:40 -07:00 committed by GitHub
parent b647a223f7
commit 69785904cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 36 additions and 728 deletions

View File

@ -290,37 +290,6 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame => AssertFrame.Attribute(frame, "data-def", "Expression value", 2));
}
[Fact]
public void SupportsAttributesWithEventHandlerValues()
{
// Arrange/Act
var component = CompileToComponent(
@"<elem attr=@MyHandleEvent />
@code {
public bool HandlerWasCalled { get; set; } = false;
void MyHandleEvent(Microsoft.AspNetCore.Components.UIEventArgs eventArgs)
{
HandlerWasCalled = true;
}
}");
var handlerWasCalledProperty = component.GetType().GetProperty("HandlerWasCalled");
// Assert
Assert.False((bool)handlerWasCalledProperty.GetValue(component));
Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 2, 0),
frame =>
{
Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType);
Assert.Equal(1, frame.Sequence);
Assert.NotNull(frame.AttributeValue);
((Action<UIEventArgs>)frame.AttributeValue)(null);
Assert.True((bool)handlerWasCalledProperty.GetValue(component));
});
}
[Fact]
public void SupportsUsingStatements()
{

View File

@ -45,13 +45,6 @@ namespace Microsoft.AspNetCore.Components
}
public static partial class BindMethods
{
public static Microsoft.AspNetCore.Components.EventCallback GetEventHandlerValue<T>(Microsoft.AspNetCore.Components.EventCallback value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static Microsoft.AspNetCore.Components.EventCallback<T> GetEventHandlerValue<T>(Microsoft.AspNetCore.Components.EventCallback<T> value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static System.MulticastDelegate GetEventHandlerValue<T>(System.Action value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static System.MulticastDelegate GetEventHandlerValue<T>(System.Action<T> value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static System.MulticastDelegate GetEventHandlerValue<T>(System.Func<System.Threading.Tasks.Task> value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static System.MulticastDelegate GetEventHandlerValue<T>(System.Func<T, System.Threading.Tasks.Task> value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static string GetEventHandlerValue<T>(string value) where T : Microsoft.AspNetCore.Components.UIEventArgs { throw null; }
public static string GetValue(System.DateTime value, string format) { throw null; }
public static T GetValue<T>(T value) { throw null; }
}
@ -442,31 +435,6 @@ namespace Microsoft.AspNetCore.Components
public UIEventArgs() { }
public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
}
public static partial class UIEventArgsRenderTreeBuilderExtensions
{
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIChangeEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIClipboardEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIDragEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIErrorEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIFocusEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIKeyboardEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIMouseEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIPointerEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIProgressEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UITouchEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIWheelEventArgs> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIChangeEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIClipboardEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIDragEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIErrorEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIFocusEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIKeyboardEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIMouseEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIPointerEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIProgressEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UITouchEventArgs, System.Threading.Tasks.Task> value) { }
public static void AddAttribute(this Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIWheelEventArgs, System.Threading.Tasks.Task> value) { }
}
public partial class UIFocusEventArgs : Microsoft.AspNetCore.Components.UIEventArgs
{
public UIFocusEventArgs() { }
@ -566,6 +534,13 @@ namespace Microsoft.AspNetCore.Components
protected void TriggerOnLocationChanged(bool isinterceptedLink) { }
}
}
namespace Microsoft.AspNetCore.Components.CompilerServices
{
public static partial class RuntimeHelpers
{
public static T TypeCheck<T>(T value) { throw null; }
}
}
namespace Microsoft.AspNetCore.Components.Forms
{
public sealed partial class EditContext
@ -740,9 +715,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
public void AddAttribute(int sequence, in Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame frame) { }
public void AddAttribute(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback value) { }
public void AddAttribute(int sequence, string name, System.Action value) { }
public void AddAttribute(int sequence, string name, System.Action<Microsoft.AspNetCore.Components.UIEventArgs> value) { }
public void AddAttribute(int sequence, string name, bool value) { }
public void AddAttribute(int sequence, string name, System.Func<Microsoft.AspNetCore.Components.UIEventArgs, System.Threading.Tasks.Task> value) { }
public void AddAttribute(int sequence, string name, System.Func<System.Threading.Tasks.Task> value) { }
public void AddAttribute(int sequence, string name, System.MulticastDelegate value) { }
public void AddAttribute(int sequence, string name, object value) { }

View File

@ -3,7 +3,6 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Components
{
@ -24,67 +23,6 @@ namespace Microsoft.AspNetCore.Components
value == default ? null
: (format == null ? value.ToString() : value.ToString(format));
/// <summary>
/// Not intended to be used directly.
/// </summary>
public static string GetEventHandlerValue<T>(string value)
where T : UIEventArgs
{
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>
public static MulticastDelegate GetEventHandlerValue<T>(Func<Task> value)
where T : UIEventArgs
{
return value;
}
/// <summary>
/// Not intended to be used directly.
/// </summary>
public static MulticastDelegate GetEventHandlerValue<T>(Action<T> value)
where T : UIEventArgs
{
return value;
}
/// <summary>
/// Not intended to be used directly.
/// </summary>
public static MulticastDelegate GetEventHandlerValue<T>(Func<T, Task> value)
where T : UIEventArgs
{
return value;
}
/// <summary>
/// Not intended to be used directly.
/// </summary>
public static EventCallback GetEventHandlerValue<T>(EventCallback value)
where T : UIEventArgs
{
return value;
}
/// <summary>
/// Not intended to be used directly.
/// </summary>
public static EventCallback<T> GetEventHandlerValue<T>(EventCallback<T> value)
where T : UIEventArgs
{
return value;
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Components.CompilerServices
{
/// <summary>
/// Used by generated code produced by the Components code generator. Not intended or supported
/// for use in application code.
/// </summary>
public static class RuntimeHelpers
{
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(T value) => value;
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>

View File

@ -224,23 +224,6 @@ namespace Microsoft.AspNetCore.Components.RenderTree
AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIEventArgs}"/>-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="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<UIEventArgs> value)
{
AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing a <see cref="Func{Task}"/>-valued attribute.
@ -258,23 +241,6 @@ namespace Microsoft.AspNetCore.Components.RenderTree
AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing a <see cref="Func{UIEventArgs, Task}"/>-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="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, Func<UIEventArgs, Task> value)
{
AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing a delegate-valued attribute.
@ -287,14 +253,6 @@ namespace Microsoft.AspNetCore.Components.RenderTree
/// <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>
/// <remarks>
/// This method is provided for infrastructure purposes, and is used to be
/// <see cref="UIEventArgsRenderTreeBuilderExtensions"/> to provide support for delegates of specific
/// types. For a good programming experience when using a custom delegate type, define an
/// extension method similar to
/// <see cref="UIEventArgsRenderTreeBuilderExtensions.AddAttribute(RenderTreeBuilder, int, string, Action{UIChangeEventArgs})"/>
/// that calls this method.
/// </remarks>
public void AddAttribute(int sequence, string name, MulticastDelegate value)
{
AssertCanAddAttribute();

View File

@ -1,10 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Forms;
namespace Microsoft.AspNetCore.Components
{

View File

@ -1,547 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.RenderTree;
namespace Microsoft.AspNetCore.Components
{
/// <summary>
/// Extensions methods on <see cref="RenderTreeBuilder"/> for event handlers.
/// </summary>
/// <remarks>
/// <para>
/// These methods enable method-group to delegate conversion for delegates and methods that accept
/// types derived from <see cref="UIEventArgs"/>.
/// </para>
/// <para>
/// This enhances the programming experience for using event handlers with the render tree builder
/// in components written in pure C#. These extension methods make it possible to write code like:
/// <code>
/// builder.AddAttribute(0, "onkeypress", MyKeyPressHandler);
/// </code>
/// Where <c>void MyKeyPressHandler(UIKeyboardEventArgs e)</c> is a method defined in the same class.
/// In this example, the author knows that the <c>onclick</c> event is associated with the
/// <see cref="UIKeyboardEventArgs"/> event args type. The component author is responsible for
/// providing a delegate that matches the expected event args type, an error will result in a failure
/// at runtime.
/// </para>
/// <para>
/// When a component is authored in Razor (.cshtml), the Razor code generator will maintain a mapping
/// between event names and event arg types that can be used to generate more strongly typed code.
/// Generated code for the same case will look like:
/// <code>
/// builder.AddAttribute(0, "onkeypress", BindMethods.GetEventHandlerValue&lt;UIKeyboardEventArgs&gt;(MyKeyPressHandler));
/// </code>
/// </para>
/// </remarks>
public static class UIEventArgsRenderTreeBuilderExtensions
{
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIChangeEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIChangeEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIChangeEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIChangeEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIDragEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIDragEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIDragEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIDragEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIClipboardEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIClipboardEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIClipboardEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIClipboardEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIErrorEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIErrorEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIErrorEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIErrorEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIFocusEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIFocusEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIFocusEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIFocusEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIKeyboardEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIKeyboardEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIKeyboardEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIKeyboardEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIMouseEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIMouseEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIMouseEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIMouseEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIPointerEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIPointerEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIPointerEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIPointerEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIProgressEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIProgressEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIProgressEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIProgressEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UITouchEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UITouchEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UITouchEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UITouchEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Action{UIWheelEventArgs}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Action<UIWheelEventArgs> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
/// <summary>
/// <para>
/// Appends a frame representing an <see cref="Func{UIWheelEventArgs, Task}"/>-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 static void AddAttribute(this RenderTreeBuilder builder, int sequence, string name, Func<UIWheelEventArgs, Task> value)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.AddAttribute(sequence, name, (MulticastDelegate)value);
}
}
}

View File

@ -399,7 +399,7 @@ namespace Microsoft.AspNetCore.Components.Test
}
[Fact]
public void CannotAddEventHandlerAttributeAtRoot()
public void CannotDelegateAttributeAtRoot()
{
// Arrange
var builder = new RenderTreeBuilder(new TestRenderer());
@ -407,7 +407,7 @@ namespace Microsoft.AspNetCore.Components.Test
// Act/Assert
Assert.Throws<InvalidOperationException>(() =>
{
builder.AddAttribute(0, "name", eventInfo => { });
builder.AddAttribute(0, "name", new Action<UIEventArgs>(eventInfo => { }));
});
}
@ -437,7 +437,7 @@ namespace Microsoft.AspNetCore.Components.Test
{
builder.OpenElement(0, "some element");
builder.AddContent(1, "hello");
builder.AddAttribute(2, "name", eventInfo => { });
builder.AddAttribute(2, "name", new Action<UIEventArgs>(eventInfo => { }));
});
}

View File

@ -2198,12 +2198,12 @@ namespace Microsoft.AspNetCore.Components.Test
{
builder.AddContent(0, "Child event count: " + eventCount);
builder.OpenComponent<EventComponent>(1);
builder.AddAttribute(2, nameof(EventComponent.OnTest), args =>
builder.AddAttribute(2, nameof(EventComponent.OnTest), new Action<UIEventArgs>(args =>
{
eventCount++;
rootComponent.TriggerRender();
childComponent.TriggerRender();
});
}));
builder.CloseComponent();
});
var rootComponentId = renderer.AssignRootComponentId(rootComponent);
@ -3638,7 +3638,7 @@ namespace Microsoft.AspNetCore.Components.Test
=> _renderHandle.Render(builder =>
{
builder.OpenElement(0, "my button");
builder.AddAttribute(1, "my click handler", eventArgs => OnClick(eventArgs));
builder.AddAttribute(1, "my click handler", new Action<UIEventArgs>(eventArgs => OnClick(eventArgs)));
builder.CloseElement();
});
}
@ -4069,12 +4069,12 @@ namespace Microsoft.AspNetCore.Components.Test
builder.OpenElement(0, "element with event");
builder.AddAttribute(1, nameof(BoundString), BoundString);
builder.AddAttribute(2, "ontestevent", (UIChangeEventArgs eventArgs) =>
builder.AddAttribute(2, "ontestevent", new Action<UIChangeEventArgs>((UIChangeEventArgs eventArgs) =>
{
BoundString = (string)eventArgs.Value;
TriggerRender();
GC.KeepAlive(unrelatedThingToMakeTheLambdaCapture);
});
}));
builder.SetUpdatesAttributeName(nameof(BoundString));
builder.CloseElement();
}