{"id":627,"date":"2023-01-30T15:24:46","date_gmt":"2023-01-30T06:24:46","guid":{"rendered":"https:\/\/sumomo.ohwaki.jp\/wordpress\/?p=627"},"modified":"2023-02-06T15:47:03","modified_gmt":"2023-02-06T06:47:03","slug":"blazor-hybrid-%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88%e3%81%a8%e3%83%9b%e3%82%b9%e3%83%88%e9%96%93i-f","status":"publish","type":"post","link":"https:\/\/sumomo.ohwaki.jp\/wordpress\/?p=627","title":{"rendered":"Blazor Hybrid-\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3068\u30db\u30b9\u30c8\u9593I\/F"},"content":{"rendered":"\n<p>\u4ee5\u524d\u3001Blazor Hybrid\u306b\u3064\u3044\u3066\u7c21\u5358\u306b\u8aac\u660e\u3057\u305f\u304c\u3001razor\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3068\u30db\u30b9\u30c8\u9593\u306e\u3084\u308a\u3068\u308a\u306b\u3064\u3044\u3066\u3001\u3082\u3046\u5c11\u3057\u8a73\u3057\u304f\u8aac\u660e\u3057\u3066\u307f\u308b\u3002(\u8a18\u4e8b\u306e\u30b3\u30e1\u30f3\u30c8\u306b\u3082\u5c11\u3005\u6587\u66f8\u3067\u66f8\u3044\u305f\u304c\u3001\u4eca\u56de\u306f\u7c21\u5358\u306a\u5b9f\u4f8b\u3067\u8aac\u660e\u3057\u3066\u307f\u308b\u3002)<\/p>\n\n\n\n<p>\u307e\u305a\u3001\u30db\u30b9\u30c8,\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u53cc\u65b9\u3067\u4f7f\u7528\u3059\u308b\u3001\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3068\u305d\u306e\u5b9f\u88c5\u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u4f5c\u6210\u3059\u308b\u3002<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-csharp\" data-file=\"I\/F\u3068\u305d\u306e\u5b9f\u88c5\" data-lang=\"C#\"><code>public delegate void OnClientEvent(object sender, EventArgs e);\npublic interface IHostInterface {\n    public string Message { get; set; }\n    public int Count { get; set; }\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u7b49\u3092\u884c\u306a\u3046\u30e1\u30bd\u30c3\u30c9\n    \/\/\/ (\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u5074\u3067\u30bb\u30c3\u30c8\u3059\u308b)\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;value&gt;&lt;\/value&gt;\n    public Action ComponentRefresh { get; set; }\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u30a4\u30d9\u30f3\u30c8\u304c\u767a\u751f\u3057\u305f\u6642\u306b\u547c\u3070\u308c\u308b\u30db\u30b9\u30c8\u5074\u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\n    \/\/\/ &lt;\/summary&gt;\n    public event OnClientEvent ComponentEvent;\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u5074\u304b\u3089\u30a4\u30d9\u30f3\u30c8\u3092\u767a\u751f\u3055\u305b\u308b\u30e1\u30bd\u30c3\u30c9\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;param name=&quot;sender&quot;&gt;&lt;\/param&gt;\n    \/\/\/ &lt;param name=&quot;e&quot;&gt;&lt;\/param&gt;\n    public void ExecClientEvent(object sender, EventArgs e);\n}\npublic class HostInterface : IHostInterface {\n    public string Message { get; set; } = null!;\n    public int Count { get; set; } = 0;\n    public Action ComponentRefresh { get; set; } = null!;\n    public event OnClientEvent ComponentEvent = null!;\n    public void ExecClientEvent(object sender, EventArgs e) {\n        ComponentEvent.Invoke(sender,e);\n    }\n}<\/code><\/pre><\/div>\n\n\n\n<p>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u5074\u3067\u306f\u3001\u3053\u306e\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092@inject\u3067Singleton\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u3001\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u3002<\/p>\n\n\n\n<p>\u4e0b\u8a18\u306e\u4f8b\u3067\u306f\u3001\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u4e2d\u306eCounter\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u30db\u30b9\u30c8\u3068\u306e\u5171\u6709\u30c7\u30fc\u30bf\u3068\u3057\u3066\u4f7f\u7528\u3057\u3001\u30db\u30b9\u30c8\u5074\u306e\u30c8\u30ea\u30ac\u3067\u3001\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u66f4\u65b0\u304c\u884c\u3048\u308b\u3088\u3046\u3001ComponentRefresh\u3067StateHasChanged\u30e1\u30bd\u30c3\u30c9\u3092\u547c\u3073\u51fa\u305b\u308b\u3088\u3046\u306b\u3057\u3066\u3044\u308b\u3002<\/p>\n\n\n\n<p>\u307e\u305f\u3001\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u5074\u306e\u30a4\u30d9\u30f3\u30c8\u3092\u3001\u30db\u30b9\u30c8\u306b\u3082\u77e5\u3089\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3088\u3046\u3001\u30a4\u30d9\u30f3\u30c8\u767a\u751f\u6642\u306b\u3001\u30db\u30b9\u30c8\u5074\u306e\u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\u3092\u547c\u3073\u51fa\u3057\u3066\u3044\u308b\u3002<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-csharp\" data-file=\"\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\" data-lang=\"C#\"><code>@inject IHostInterface HostIF\n\n&lt;h1&gt;Counter&lt;\/h1&gt;\n\n&lt;p&gt;Current count: @HostIF.Count&lt;\/p&gt;\n\n&lt;button class=&quot;btn btn-primary&quot; @onclick=&quot;IncrementCount&quot;&gt;Click me&lt;\/button&gt;\n\n@code {\n    protected override void OnInitialized() {\n        \/\/ Component\u306e\u518d\u63cf\u753b\u30e1\u30bd\u30c3\u30c9\u3092\u8a2d\u5b9a\n        HostIF.ComponentRefresh = (Action)(()=&gt;StateHasChanged());\n    } \n\n    private void IncrementCount() {\n        \/\/ \u30ab\u30a6\u30f3\u30c8\u30a2\u30c3\u30d7\u3057\u305f\u5f8c\u3001\u30db\u30b9\u30c8\u5074\u3078\u30a4\u30d9\u30f3\u30c8\u901a\u77e5\n        HostIF.Count++;\n        HostIF.ExecClientEvent(this,new EventArgs());\n    }\n}<\/code><\/pre><\/div>\n\n\n\n<p>\u30db\u30b9\u30c8\u5074\u3067\u306f\u3001\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3067\u3001ComponentEvent\u306b\u30cf\u30f3\u30c9\u30e9\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u72b6\u614b\u5909\u66f4\u304c\u6709\u3063\u305f\u5834\u5408\u306e\u51e6\u7406\u3092\u5b9a\u7fa9\u3067\u304d\u308b\u3002<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism undefined-numbers lang-csharp\" data-file=\"HOST\u5074\u51e6\u7406\" data-lang=\"C#\"><code>private HostInterface HostIF;\npublic Form1()\n{\n    InitializeComponent();\n    var services = new ServiceCollection();\n    services.AddWindowsFormsBlazorWebView();\n    \/\/ Singleton\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\n    HostIF = new HostInterface();\n    \/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u304b\u3089\u547c\u3073\u51fa\u3055\u308c\u308b\u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\n    HostIF.ComponentEvent += On_ClientEvent;\n    \/\/ Singleton\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30b5\u30fc\u30d3\u30b9\u306b\u8ffd\u52a0\n    services.AddSingleton&lt;IHostInterface&gt;(HostIF);\n    blView.HostPage = @&quot;wwwroot\\index.html&quot;;\n    blView.Services = services.BuildServiceProvider();\n    blView.RootComponents.Add&lt;Counter&gt;(&quot;#app&quot;);\n}\n\/\/\/ &lt;summary&gt;\n\/\/\/ \u30a4\u30f3\u30af\u30ea\u30e1\u30f3\u30c8\u30dc\u30bf\u30f3\u30af\u30ea\u30c3\u30af\u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;sender&quot;&gt;&lt;\/param&gt;\n\/\/\/ &lt;param name=&quot;e&quot;&gt;&lt;\/param&gt;\npublic void On_btnIncrement_Click(object sender, EventArgs e) {\n    \/\/ Singleton\u306e\u30ab\u30a6\u30f3\u30bf\u3092\u30a4\u30f3\u30af\u30ea\u30e1\u30f3\u30c8\n    HostIF.Count++;\n    lblMessage.Text = $&quot;\u30ab\u30a6\u30f3\u30c8\uff1a{HostIF.Count}&quot;;\n    \/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u8868\u793a\u3092\u66f4\u65b0\n    HostIF.ComponentRefresh();\n}\n\/\/\/ &lt;summary&gt;\n\/\/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=&quot;sender&quot;&gt;&lt;\/param&gt;\n\/\/\/ &lt;param name=&quot;e&quot;&gt;&lt;\/param&gt;\npublic void On_ClientEvent(object sender, EventArgs e) {\n    \/\/ \u30db\u30b9\u30c8\u306e\u8868\u793a\u3092\u66f4\u65b0\n    lblMessage.Text = $&quot;\u30ab\u30a6\u30f3\u30c8\uff1a{HostIF.Count}&quot;;\n}<\/code><\/pre><\/div>\n\n\n\n<p>\u5b9f\u884c\u3059\u308b\u3068\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u3001\u30db\u30b9\u30c8\u3068\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u9593\u306e\u540c\u671f\u304c\u53d6\u308c\u3066\u3044\u308b\u3053\u3068\u304c\u5206\u304b\u308b\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"803\" height=\"495\" src=\"https:\/\/sumomo.ohwaki.jp\/wordpress\/wp-content\/uploads\/2023\/01\/9f485b798dd35eeb7ccbd7b965ab8e39.png\" alt=\"\" class=\"wp-image-631\" srcset=\"https:\/\/sumomo.ohwaki.jp\/wordpress\/wp-content\/uploads\/2023\/01\/9f485b798dd35eeb7ccbd7b965ab8e39.png 803w, https:\/\/sumomo.ohwaki.jp\/wordpress\/wp-content\/uploads\/2023\/01\/9f485b798dd35eeb7ccbd7b965ab8e39-300x185.png 300w, https:\/\/sumomo.ohwaki.jp\/wordpress\/wp-content\/uploads\/2023\/01\/9f485b798dd35eeb7ccbd7b965ab8e39-768x473.png 768w\" sizes=\"auto, (max-width: 803px) 100vw, 803px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"480\" style=\"aspect-ratio: 852 \/ 480;\" width=\"852\" controls src=\"https:\/\/sumomo.ohwaki.jp\/wordpress\/wp-content\/uploads\/2023\/02\/BlazorHybridSample.mp4\"><\/video><\/figure>\n\n\n\n<p>\u4f55\u304b\u306b\u4f7f\u3048\u308b\u304b\u3082\u77e5\u308c\u306a\u3044\u306e\u3067\u3001\u30e1\u30e2\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4ee5\u524d\u3001Blazor Hybrid\u306b\u3064\u3044\u3066\u7c21\u5358\u306b\u8aac\u660e\u3057\u305f\u304c\u3001razor\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3 &hellip; <a href=\"https:\/\/sumomo.ohwaki.jp\/wordpress\/?p=627\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,10,9,4],"tags":[],"class_list":["post-627","post","type-post","status-publish","format-standard","hentry","category-net","category-blazor","category-c","category-4"],"_links":{"self":[{"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=627"}],"version-history":[{"count":8,"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/627\/revisions"}],"predecessor-version":[{"id":641,"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/627\/revisions\/641"}],"wp:attachment":[{"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sumomo.ohwaki.jp\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}