WPFはWinformよりここがいいぞというお話


　こんにちは。個人的な信仰心により全ての女性はひつじであると考えているただの無害なヒツジ好きです。

　WPFに関してはどういう訳か未だに「Winformの方が長年のノウハウがあっていい」とかいう意見がTwitter辺りでもちらほら見かけるので、個人的にWPFのここがWinFormよりすぐれているという部分（比較）を書いていきます。

　個人的にはWPFがあまり普及しないのはBindingとかMVVMとか、**初心者には余計な前情報が多すぎる** からです。そんなのなくても基本的なFormアプリ実装は十分出来るし、それだけなら従来のWinFormと見た目的にもそれほど変わりません。



# 拡張性やメンテナンス性に優れる

　僭越ながら自作の成果物を例に取らせて頂きます。


 ![20221017162647.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145714/b25cd96b-dafd-7be9-b252-46223b4e608e.png)


　例えば **タブコントロール**　をあとから追加したくなった場合、WinFormだとそんな簡単に追加出来ません。デザイナだと殆ど最初からプロジェクトを作りなおすか、一時的に子要素にするコントロールを背面にしてごちゃごちゃ弄るか、コードビハインド（Designer.csとか）側で実装する事になるかと思います。この辺は長年Winformでアプリ制作をしてきた人には何等かのノウハウがあるのかも知れません。


 これがWPFだと後から XAMLで

```C#:XAML
<TabControl> <TabItem>
<contorole/>
<contorole/>
<contorole/>
</TabItem></TabControl>
```

と書き足していくだけなので非常に楽です。




# カッコいい見た目のUIを作れる
　WPF制作のアプリケーションにNeeView　[(https://bitbucket.org/neelabo/neeview/wiki/Home)](https://bitbucket.org/neelabo/neeview/wiki/Home "https://bitbucket.org/neelabo/neeview/wiki/Home")がありますが、このように非常にカッコいいモダンなUIが作れます。やろうと思えばアニメーションさせたり出来ます（このアプリではLoding中にアニメーションさせたりしている）。



# XAMLだからコピペでデザインを手軽に共有出来る
　Winformにない利点の一つ。WinfromでUIを共有しようと思ったらInitializeComponent()内の処理を自分で書く必要がある。当然ながら読者側のデザイナには何も出せない。
 XAMLならコピデで一発。



# コントロールのプロパティにDataBindingが記述出来る
　この辺はDataBindなんて知らなくても書けるよ！という前提から外れてしまいますが、これはこれで便利な仕組みで（WinFormはやり方を知らないから書けない）、実装も簡単なんで挙げておきます。これを使えると、例えば　**コントロールのTextプロパティを特定のフィールド変数に自動的に割り当てる** という事が可能で、**TextBoxに入れたテキストをイベントハンドラでの実装無しでフィールド変数に代入出来ます。**

Codeも簡潔になり便利です。こんな感じで

```C#:XAML
<TextBox Width="390"
x:Name="ParamText" Text="{Binding StartQuery}"  TextChanged="Param_TextChanged" FontSize="16"   
                                               />
```

コードビハインド（実装.cs 側）では、string StartQueryをメンバ変数として持ったClassを定義する必要があります。これをコンストラクタ等でDataContextに代入してやります。


```C#:C#
 public class DataContextClass
    {

       public string StartQuery { get; set; }
       public string OutputPath { get; set; }
       public string endString { get; set; }
       public string _LoadArguments { get; set; }

    }


///コンストラクタ

//DataContextClass
DataContextClass　DCmenber;

public mainForm()
{
 //オブジェクト初期化子で設定
DCmenber = new DataContextClass()
        {
           StartQuery = "ffmpegQuery")

          //個人的な実装なので省略
          //      OutputPath = ParamInterfase.OutputDirectory,
          //      endString = ParamInterfase.endFileNameStrings
                };}

                DataContext = DCmenber;
}
```

尚、DataContextを複数持つという事は出来ないようです。クラス毎に一つしか持てない仕様なのかなと。多分。

以下は自作アプリでの適用例。テキストボックス内のFFmpegに渡すパラメーターを書き換えるとStartQuery変数にも自動的に割り当てられます。いちいちTextChangedとか使わないで実装出来るので楽です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145714/0063d2a4-bd7a-84c8-3931-a9732d309bd0.png)




# Winformのここがクソだよという点

　ちょっと難しい事をやろうとしてもOnPaintをオーバーライドとかさせたりするような古くて役に立たなそうな記事が出てきて実現できない事が多い。すぐ詰まる。
　シレっとWin32APIを使った実装とかズラズラ出てくる。
　なかなかコンパイル通らないからと自分で実装を書かずに安易に他から流用しようとする人が増える。
 defaultで見た目がダサイ。色々改造すると挙動もなんか変な感じになったりする。

# WPFの難点
・Winformのやり方に慣れてしまうとUIの実装が難しそうに見える。
　→XAMLの書き方が難しそう

・MVVM実装を強要している（ように見える）
→実際はイベント登録も普通に出来るし、Winformと同じ様に書ける
→MVVMパターン実装もやりましたが言うほど難しいものでは無いし、後入れ対応も可能でした。習うより慣れろ
私はChatGPTでサンプルコードを出力させて覚えました。

・**コードビハインドに何も書くな** とか初心者的に訳の分からない事言い出す人が多い

　→UI関連の処理なら普通に書いていいと思う。WinFormみたいに書きすぎると可読性やメンテナンス性が落ちるので段階的にViewModelとして分離していく必要はある。
　→というか大きなお世話で、書きたいときに書きたい場所に書く方が健全である。メンテナンス性を高める手法は色々あるので段階的に追加すればよい。

# 自作のXAMK書き方記事
【WPF超入門】XAML要素の基本的な書き方を整理してみる記事

https://qiita.com/EndOfData/items/c8c2c6229a76526f85ed

いいね数0だけどまあ大目に見ようという事で。


# WPFのここがダメだよと言う点（制限事項）

・任意のクラスを継承出来ない
あくまでWinformと比べてですがXAMLと連携する仕様上、**任意のクラスを継承する事が出来ません**　代わりにInterfaceを使います。

・DataContextは複数持てない（上書きされる）
この解決方法は、個別のコントロール毎にBindingを書いてやらないといけないという事です


下記のMainWindowのDataContextと共存させるには？を参照

https://qiita.com/EndOfData/items/2e8bbd04f78a9b6d27de


### MVVMってもうPrismがデフォっぽい？
普通に便利だという話を聴いたので。勉強のためと自力で実装する事にあまり意味はない気がします。

https://qiita.com/toydev/items/cf1bb4b519e7e2453d46