.NET Core 3.x + VB でも WinForms がしたい！

# はじめに
これは、[Visual Basic Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vb)の15日目の記事となります。

※.NET Core 3.x というタイトルですが、.NET Core 3.1 を使ってます。

【2019/12/21追記】
Visual Studio のプレビュー版 Visual Studio 16.5 Preview 1 で、WinForms (.NET Core) がデザイナでプレビューできるようになりました。
[Updates to .NET Core Windows Forms designer in Visual Studio 16.5 Preview 1](https://devblogs.microsoft.com/dotnet/updates-to-net-core-windows-forms-designer-in-visual-studio-16-5-preview-1/)

# テンプレートにVBが無い
@tfukumori さんの「[VB.NETの.NET CoreにおけるWinForms、WPFのサポートはどうなるのか](https://qiita.com/tfukumori/items/0c0702b8c542c0ab054e)」記事にあるようにテンプレートにVBがありません。

下記サイトによるとVBのサポートは残念ながら `.NET 5` になったようです。`.NET 3.1`でも駄目でした。

* [.NET Core 3.0 VB WPF/Winforms Templates are disappeared](https://developercommunity.visualstudio.com/content/problem/725398/net-core-30-vb-wpfwinforms-templates-are-disappear.html)
* [Remove WPF VB Templates #1734](https://github.com/dotnet/wpf/issues/1734)

既存のプロジェクトテンプレートだとVBには対応していませんが`.csproj`と同じような形に`.vbproj`ファイルを書き換えればVBでもWindows Formsアプリケーションを作成することが可能です。
[.NET Core 3.0 + F# でも WinForms がしたい！](https://qiita.com/ethansan3/items/0142dc67f2b6c675f210)

## 環境
* Visual Studo 2019 Version 16.4.0 → 16.5 Preview 1
* .NET Core SDK 3.1

# プロジェクトファイル
VBでもやってみました。 テンプレートについてはまだ理解が足りていないのか少しやってみたのですが駄目でした。

```xml:VBWinFormApp.vbproj
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <StartupObject>VBWinFormApp.Form1</StartupObject>
  </PropertyGroup>

</Project>
```

特筆すべき点は特にないかもしれませんが、`Sdk`を`"Microsoft.NET.Sdk.WindowsDesktop"`に、`<OutputType>をWinExe`に、`<UseWindowsForms>`を`true`に設定するぐらいでしょうか

```xml:VBWinFormApp.vbproj.user
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup />
  <ItemGroup>
    <Compile Update="Form1.vb">
      <SubType>Form</SubType>
    </Compile>
  </ItemGroup>
</Project>
```

スタートアップオブジェクトを`Sub Main`から`Form1` にします。

# ソース
```VB:Form1.vb
Public Class Form1

End Class
```

```VB:Form1.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Windows フォーム デザイナーで必要です。
    Private components As System.ComponentModel.IContainer

    'メモ: 以下のプロシージャは Windows フォーム デザイナーで必要です。
    'Windows フォーム デザイナーを使用して変更できます。  
    'コード エディターを使って変更しないでください。
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(800, 450)
        Me.Text = "Form1"
    End Sub

End Class
```

# 結果
Windows Formsデザイナは表示されてこなかったですが、ビルドしたらフォームが出てきました。

![VBWinForm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/5aeee6f5-4248-5fe2-920f-3a9dc9a653f7.png)

C# でもWindows Formsデザイナは表示されてこなかったので、`.NET Core Windows Forms Designer` の別途インストールが必要かも知れません。後で確認しておきます。

## 2019/12/21追記
Visual Studio 16.5 Preview 1 で、オプションでプレビュー機能を有効にする必要がありますが、Windows Formsデザイナが表示されるようになりました。
[みなさんお待ちかね！ WinForms がデザイナでポトペタ可能に！！](https://rksoftware.hatenablog.com/entry/2019/12/13/210322)

C# でポトペタが出来ることを確認した後に、VBでもポトペタができることを確認しました。
![VBWinForm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/94563b05-b7f9-41ee-91fb-923f0d780b16.png)

残念なところとして、ボタンを配置してクリックイベントの連携である `Handles`句が自動で記述されるようにはなっていませんでした。ここは手動で記述する必要があります。
追記すればイベント処理が呼ばれてメッセージボックスが表示されてきます。

```vb:ボタンイベント
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show("Hello! .NET Core 3.0")
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs)

    End Sub
End Class
```

![VBWinForm3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/a53ea312-c6ac-6007-2778-ca5e3b6a188f.png)


# 最後に
Microsoft担当者の発言によると
>Microsoftには、アプリケーションイベント、アプリケーションモデル、シングルインスタンスアプリケーションなどのVB機能を完璧にしてから、テンプレートを追加したい、という意向がある。

個人プロジェクトとしてなら、無理矢理でもプロジェクトを作成することでVBが使用出来るのですが、仕事としてはMicrosoftが公式に作成してくれないことには現状では使用出来ないですね。