-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathStronglyTypedEvents.cs
100 lines (83 loc) · 3.55 KB
/
StronglyTypedEvents.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using System.Runtime.InteropServices.JavaScript;
using System.Threading.Tasks;
namespace WasmBrowser.Recipes.WasmClient.Examples.StronglyTypedEvents;
// This example builds upon EventsProxy.cs and EventsShims.js
public interface IJSObjectWrapper { JSObject JSObject { get; } }
public class Element(JSObject jsObject) : IJSObjectWrapper
{
public JSObject JSObject { get; } = jsObject;
// SubscribeEvent click listener function
public void InstanceClickListener(JSObject eventObj)
{
Console.WriteLine($"[ClickListener handler] Event fired with event type via interop property '{eventObj.GetPropertyAsString("type")}'");
PrimitivesProxy.ConsoleLog(eventObj);
}
public delegate void JSObjectWrapperEventHandler<in TSender, in TEventArgs>(TSender sender, TEventArgs e)
where TSender : IJSObjectWrapper;
private JSObjectWrapperEventHandler<Element, JSObject> onClick;
const string EventName = "click";
private JSObject JSListener { get; set; }
public event JSObjectWrapperEventHandler<Element, JSObject> OnClick
{
add
{
// We have only one JS listener, and can proxy firings to all C# subscribers
if (onClick == null) // if first subscriber, then add JS listener
{
JSListener = EventsProxy.SubscribeEvent(this.JSObject, EventName, JSInteropEventListener);
}
// Always add the C# subscriber to our event collection
onClick += value;
}
remove
{
if (onClick == null)// if no subscribers on this instance/event
{
return;// nothing to remove
}
onClick -= value; // else remove susbcriber
if (onClick == null) // if last subscriber removed, then remove JS listener
{
EventsProxy.UnsubscribeEvent(this.JSObject, EventName, JSListener);
}
}
}
// When the JS event is fired, this listener is called, and fires the C# event
private void JSInteropEventListener(JSObject eventObj)
{
onClick?.Invoke(this, eventObj);// fire event on all subscribers
}
}
public partial class Document
{
public static Element GetElementById(string id)
{
JSObject jsObject = StronglyTypedWrapper.DocumentProxy.GetElementById(id);
return new Element(jsObject);// Wrap the JSObject in our Element wrapper.
}
}
public static class StronglyTypedEventsUsage
{
public static async Task Run()
{
await JSHost.ImportAsync(StronglyTypedWrapper.DomShimModule.ModuleName, $"/{StronglyTypedWrapper.DomShimModule.ModuleName}.js");
var element = Document.GetElementById("btn3");
Element.JSObjectWrapperEventHandler<Element, JSObject> test =
(Element sender, JSObject e) => {
Console.WriteLine($"[Strongly Typed Event Handler] Event fired through C# event '{e.GetPropertyAsString("type")}'");
// Log sender and event object
PrimitivesProxy.ConsoleLog(sender.JSObject);
};
Console.WriteLine("+= test");
element.OnClick += test;
EventsProxy.TriggerClick("btn3");// trigger event to test hander
Console.WriteLine("-= test");
element.OnClick -= test;
EventsProxy.TriggerClick("btn3");// trigger event again to verify event no longer fired
Console.WriteLine("+= test");
element.OnClick += test;
EventsProxy.TriggerClick("btn3");
}
}
// The example displays a red "New Hello!" element in the browser.