カップ麺シリーズ:WPFを中心としたMVVM論

はじめに この記事は、そこそこ攻撃的な内容になります。不快に思ったなら、その時点でブラウザバックをしてください。 MVVM とは? MVVMは言うまでもなく Model - View - ViewModel を利用した設計手法で、WPFのみならず .NET MAUI などでも利用されます。 そこで、MVVMを活用するにはどうすればいいのか、という点を中心に語りたいと思います。 まず、論外なのは ViewModel と Model を相互参照するパターンです。 View は ViewModel を知っているが、ViewModel は View を知らない。ViewModel は Model を知っているが、Model は ViewModel を知らない。これが大原則です。 何故かというと、Model とはそれ単体でアプリケーションロジックを全て網羅してるからです。特定の ViewModel に依存してはいけません。 例えば、WPF でアプリケーションを作っている時に、Model は「Modelさえ流用すればコンソールアプリだって作れる」そういう状況が理想です。 …いや、理想っていうか、MVVMってそういうモノなんですけどね? 故に、Model が ViewModel を参照しているサイト…正直私も参照したことがありますが、あの人はおそらく MVVM の根本を分かっていないでしょう。 Model から ViewModel に何かを伝えるためには? Model は ViewModel を知らないのが大原則、ではどうすればいいのか?一応の答えは「イベント通知」になります。 ただし、ある程度の規模になると面倒で複雑で、正直やっていられません。私もサンプルコードを提示できません。 ただし、PrismのEvent AggregatorやCommunityToolkit.MVVMのMessengerといったメッセージングを使えるなら、話はグッと楽になります。 Model から ViewModel にメッセージを飛ばせば良いのです。 メッセージングを利用することで疎結合が守られ、ユニットテストも容易になり、さらにViewModelに依存しない構成を作れます。 さて、ここで読者の皆さんは何か気づきませんか?思い当たる節がなければそれに超したことはありませんが… Model で ObservableCollection を使うのは基本的に誤りです!ObservableCollection は ViewModel から View に更新通知するコレクションですから。...

2024年11月23日 · (2024年12月06日 更新) · 1 分 · もりゃき

カップ麺シリーズ:一から学べる、WPFでの多言語対応方法

多言語対応をしよう 今やグローバル時代!世界を相手にしなければ勝てない! そう、東京弁だけでなく大阪弁、名古屋弁、博多弁など…ごめんなさい調子に乗りました、単純に「日本語」「英語」「ロシア語」対応について語ります。 真面目な話、ソフトウェアで最低限英語対応すると、ターゲットが英語圏の人にまで届く可能性が高まります。 もちろん、ドキュメントも英語化が必要ですけど、今ならDeepLとか使えば便利にそれっぽく翻訳してくれますからね。 さらにChatGPTで添削とかさせれば、ニュアンス踏まえて指摘してくれますよ! 今回は、WPFにおいてViewとViewModelだけを使った、極めてシンプルな多言語対応サンプルを示したいと思います。 プロジェクト作成 今回は「WPFアプリケーション」で MultiLanguageTest というプロジェクトを作りましょう。フレームワークは「.NET 9.0」を使用します。 そして開かれた MainWindow.xaml を以下のようにしましょう。 「Language」の中に「Japanese」「English」「Russian」として、ウィンドウ内全域にボタンを貼り付けているだけです。 <Window x:Class="MultiLanguageTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:MultiLanguageTest" mc:Ignorable="d" Title="MultiLanguageTest" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Menu> <MenuItem Header="Language"> <MenuItem Header="Japanese" Command="{Binding ToJapanese}"/> <MenuItem Header="English" Command="{Binding ToEnglish}"/> <MenuItem Header="Russian" Command="{Binding ToRussian}"/> </MenuItem> </Menu> <Button Grid.Row="1" Margin="5" Content="{Binding Greetings}" Command="{Binding ExecuteGreetings}"/> </Grid> </Window> シンプルなテストなので、UIに関しては最低限の実装になっています。画面とかは本題じゃないからいいよね? 下準備に CommunityToolkit.Mvvm の導入 利便性のため、NuGetで CommunityToolkit.Mvvm を導入します。 メニューの「ツール」-「NuGetパッケージマネージャ」-「ソリューションのNuGetパッケージの管理」から、 「参照」タブをクリックしてCommunityToolkit.Mvvm を検索してプロジェクトにインストールします。...

2024年11月12日 · (2024年11月14日 更新) · 3 分 · もりゃき

カップ麺シリーズ:一から学べるWPF における CommunityToolkit.Mvvm(MVVM ToolKit) 覚え書き(3) メッセージングの簡単なサンプル

プロジェクトの準備 この記事では、メッセージングの利用自体は簡単であることを実感してもらうため、コンソールアプリケーションでの、新規プロジェクトによるサンプルとなります。 Visual Studioから「新しいプロジェクト」で「C#」「Windows」経由で「コンソール アプリ」を選び、プロジェクト名は「MessagingTest」にして、ソリューションを作成してください。今回はプロジェクト名を変更しても問題ありません。 フレームワークは「.NET 9.0」を使用します。 MVVM Toolkfit の利用準備 ソリューションに対し、Visual Studioのメニュー「ツール」「NuGetパッケージマネージャ」から「ソリューションのNuGetパッケージの管理」を選び、「参照」タブから CommunityToolkit.Mvvm をインストールします。 (1)基本のメッセージング まずはProgram.csを全削除し、以下の内容に置き換えます。この際、コピペでは身につかないとか言いません。プロジェクトを作って動かせば、見えてくるものもあるでしょう。 using CommunityToolkit.Mvvm.Messaging; namespace MessageingTest { /// <summary> /// 送信クラス(Main含む) /// </summary> public static class Sender { public static void Main() { // 保持する必要はないが、ここでは受信クラスを作る必要がある var _ = new Receiver(); // 弱い参照でのメッセージング var message = new MyMessage("もりゃき", 12); WeakReferenceMessenger.Default.Send(message); // メッセージが出力されるまで待機 Console.ReadKey(); } } /// <summary> /// 受信クラス /// </summary> public class Receiver { public Receiver() { // 弱い参照での受信設定 WeakReferenceMessenger....

2024年05月26日 · (2024年11月14日 更新) · 4 分 · もりゃき

カップ麺シリーズ:一から学べる、WPF における CommunityToolkit.Mvvm(MVVM ToolKit) 覚え書き(2) 依存性注入を利用した簡単なサンプル

前提条件 まずは 「WPF における MVVM ToolKit覚え書き(1) 簡単な依存性注入とデータバインディング」 を完読して、プロジェクトを作成してください。 DIを使うための、新しいウィンドウViewName を作成する ソリューションエクスプローラーで「Views」フォルダで「追加」から「ウィンドウ(WPF)」を選び、名前に ViewName.xaml と設定してウィンドウを作成します。 そして以下のように置き換えます。 <Window x:Class="NameTest.Views.ViewName" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:NameTest.Views" mc:Ignorable="d" Title="ViewName" Height="450" Width="800"> <Grid VerticalAlignment="Center"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Grid.Row="0" Width="300" Height="30" Content="あなたの名前"/> <TextBox Grid.Row="1" Width="300" Height="30" Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}"/> </Grid> </Window> 次に、ViewModelsフォルダにおいて「追加」から「クラス」を選び、名前に ViewNameViewModel.cs と設定してクラスを追加します。 内容は無視して以下のように書き換えます。 using CommunityToolkit.Mvvm.ComponentModel; namespace NameTest.ViewModels { public interface IViewNameViewModel; public class ViewNameViewModel : ObservableObject, IViewNameViewModel { private string _name = string.Empty; public string Name { get => _name; set => SetProperty(ref _name, value); } } } そして、このViewModelをDIコンテナに登録します。App....

2024年05月25日 · (2024年12月06日 更新) · 3 分 · もりゃき

カップ麺シリーズ:一から学べるWPF における CommunityToolkit.Mvvm(MVVM ToolKit) 覚え書き(1) 簡単な依存性注入とデータバインディング

プロジェクトの準備 Visual Studioから新しいプロジェクトで「C#」「Windows」経由で「WPFアプリケーション」を選び、プロジェクト名は「NameTest」にして、ソリューションを作成してください。これでソリューションも NameTest になります。説明通りに動かないことを避けるため、この記事に関しては可能な限りソリューション名を NameTest にしてください。 フレームワークは「.NET 9.0」を使用します。 この「WPF における CommunityToolkit.Mvvm 覚え書き」シリーズは、ある程度のMVVM知識を有していることを前提としております! 簡単に言うとViewは見た目、ViewModelはViewにデータバインディグする関連の処理、Modelはアプリケーションのコアとなる処理群ですね。大規模プロジェクトなら、おそらくModelが一番大きくなります。 MVVM Toolkit の利用準備 ソリューションに対し、Visual Studioのメニュー「ツール」「NuGetパッケージマネージャ」から「ソリューションのNuGetパッケージの管理」を選び、「参照」タブから CommunityToolkit.Mvvm をインストールします。 Microsoft.Extensions.DependencyInjection も同様にインストールします。 もちろん理解している方なら、コマンドからInstall-Package CommunityToolkit.Mvvm等としても構いません。 Ioc - 制御の逆転って? DI(依存性注入)については、簡単に言うと、オブジェクトの生成や依存関係の解決を外部(具体的には後に出てくる App.xaml.cs)に委譲することで、コードの柔軟性とテストの容易さを向上させるパターンです。この記事では、具体的な手順を通じてDIの使い方を学びます。 何より大切なのは、自分でソリューションを作り、手を動かすことです。コピペしても何も習得できず、応用が利きません。 App.xamlの書き換え まずは MVVM としてのスタンダードとして、プロジェクト直下に [追加] から [新しいフォルダ] を利用して Views 、ViewModels そして Models フォルダを作ります、(今回は Models 使わないので省いていいですけど、一般的な構成として覚えておいてください、すなわち大規模アプリケーション開発に直接アドバイスする記事ではありません)。 プロジェクト直下にある MainWindow.xaml を Views にドラッグドロップで移動します。移動時、名前空間も調整してください。 そして App.xaml を以下のように調整してください。 <Application x:Class="NameTest.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:NameTest" StartupUri="MainWindow.xaml"> <Application.Resources> </Application.Resources> </Application> から <Application x:Class="NameTest.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:NameTest" StartupUri="Views/MainWindow.xaml"> <!...

2024年05月20日 · (2024年11月14日 更新) · 3 分 · もりゃき

カップ麺シリーズ:C#でSHGetFileInfoをDllImportからLibraryImportに書き換え

最低限DllImportの使い方を理解している方を対象にしています。この記事をコピペで利用した際の責任は一切負いません あの、C# で Windowsのファイルアイコンやら色々な情報を獲得する SHGetFileInfo の宣言を、DllImportからLibraryImportに書き換えて、憎きSYSLIB1054を一つ撲滅する方法をお伝えします。 まず、C# での DllImportのパターンは、よく見るのはこういう宣言ですね。 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; [DllImport("shell32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttribs, ref SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags); そして SHGETFILEINFO の使い方はこんな感じですよね? SHFILEINFO shinfo = new(); IntPtr shFileInfoResult; // ここ shFileInfoResult = SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal....

2023年12月14日 · (2024年12月06日 更新) · 2 分 · もりゃき

少子高齢化社会に向けた持続可能性社会の提言、大きな政府による福祉政策と低所得者層救済案

結論から リベラルは増税を恐れず、大きな政府を目指すべきだと、強く考えています。 リベラルはしばしば減税(特に消費税減税)を訴えてますが、 消費税による税収は既に税収の30%と莫大になっている現状において、 消費税減税や消費税撤廃は既に現実的な選択肢ではなくなっているのではないかと考えます。 本当に消費税の穴埋めとして、法人税や所得税だけで穴埋めできるのでしょうか? 個人的には、消費税は本当に好きじゃないですけど、撤廃して欲しい位ですけど、 それでは済まないという現実があるのではないかと考えます。 福祉問題 現在、福祉従事者は極めて過酷な状況で働いています。 福祉に限らず保育所などのケア労働分野でも同様のことが起こっているでしょうが、ここでは福祉従事者を焦点に当てます。 私自身、重度身体障私自身害者として福祉サービスを受けていますが、 その領収書に記載されている金額から考えると、福祉従事者の時給はおそらく1000円を下回ることが推測されます。 これは言うまでもなく、国からの補助金などが削減されているからです。 そんな状況で、今後、若者達が望んで福祉業務に携わるでしょうか? 上記の状況において、そんな期待はできないでしょう。 昨今では、外国人労働者受け入れの話題も上がっていますが、そもそも福祉業界の待遇が悪ければ上手く行くはずがありません。 しかし、福祉業界の待遇が良ければ、外国人側から日本への福祉業界参入に関する打診さえ期待できるでしょう。 財源の問題 MMT理論に基づけば、自国通貨をどんどん発行すればいい…となりますが、 自国通貨を無制限に発行すれば更なる円安進行、物価高が進行することは明白です。 現状でも円安と物価高が進行している中、MMT理論を仮に採用していたら、 さらなる経済危機が避けられなかったはずです。 無制限な通貨発行が可能という考え方は、既に現実的には誤りである、そう明白に結果に出ていると言っていいでしょう。 では、どうすればいいか?単純かつ受け入れがたい結論ですが、増税しかないでしょう。 大きな政府 リベラルは自民党を「新自由主義」と叩きますが、 そう叩くのであれば論理的に「反新自由主義」のリベラルこそ「大きな政府」を志向しなければ筋が通りません。 新自由主義は「小さな政府」を目指す思想であり、 大ざっぱに言うなら「可能な限り民間に仕事をさせ、福祉を縮小する」という方向性です。 福祉を重視する、しかし財源が厳しいのであれば、 「増税して、福祉を充実させる」というのは論理的に当然の帰結になります。 自民党は極端な新自由主義を推進しているとは思いません、 むしろ保守的な自由主義に新自由主義を織り交ぜた、 国民への一定の社会保障を提供するバランスを取る、 現状維持政策といえるでしょう。 それでもリベラルが自民党を新自由主義だと批判するのであれば、 リベラル自身が増税を伴う「大きな政府」を掲げる覚悟が必要でしょう。 そもそも「福祉などの充実」と「減税」は、実現不可能に近いポピュリズム的な政策なのですから。 「大きな政府」を訴えることができるのは、リベラルだけなのですから。 福祉問題に留まらない低所得者層の救済案 「大きな政府」は、言い換えれば「高福祉・高負担社会」、もっと俗に言えば「北欧型社会」を指します。 現在の日本では、税金が「お上に吸い上げられているだけ」という感覚が強くあります。 しかし、例えば消費税に対して、低所得者層への還元を行う「負の消費税」など、 負担が過大な人に還元を行う政策を導入することが考えられます。 さらに、他の還元政策が実現すれば、税金の使い道に透明性が生まれ、 自分たちにしっかり還元されているという実感を得られるようになります。 これにより、国民の税金に対する意識も変わるでしょう。 仮に税金が高くなっても、低所得者層に対する十分な還元があり、 生活の質が向上すれば、国民生活全体の水準も引き上げられるはずです。 また、「負の所得税」の導入も検討に値します。 所得税は通常、納税の対象ですが、 一定の所得以下の人には政府が補助金を支給することで、生活を支援する仕組みです。 これらより重要な話として、生活保護受給者の医療は、医療券によって医療費が無料になりますが、 生活保護を受けられない低所得者層は、はるかに重い医療費負担を強いられています。 このような不平等を是正するため、大きな政府が目指す社会では、平等性を重んじ、 例えば医療費を所得に応じて累進的に軽減する仕組みを導入することが適切でしょう。 もちろん、これらの施策を実現するには、一時的に「増税の痛み」を伴います。 敢えて今まで挙げた政策に、優先順位を付けるなら以下のようになるでしょう。 医療費軽減(最優先:最悪の場合、命に関わる) 負の消費税(逆進性が強く、低所得者層へのダメージが大きい) 負の所得税(中長期的な効果が見込まれる) これらが一度に実現されるとは、私自身思っていません。段階的な実現になるはずです。 しかし、それでもこれらの施策をもって、迅速に低所得者層への還元を行うことで、 その負担を上回る生活の向上を実感できるはずです。 大きな政府としての日本は、おそらく「日本型」になる 「北欧型」という言い回しをしましたが、おそらく北欧のモデルをそのまま日本に持ち込んでも上手く行きません。 日本と北欧諸国では、文化面を中心にあらゆる点が異なっています。 日本は「輸入依存型の社会」ですから、北欧とはかなり異なった形を取ることになるでしょう。 故に「日本型大きな政府」は日本独自のモデルとなり、今後の少子高齢化社会のモデルとして有益になる可能性は高いです。...

2024年09月12日 · (2024年12月06日 更新) · 1 分 · もりゃき

TwitterとFacebookをBANしました

えっと、WPF Prismの記事更新を放置しながら申し訳ないのですが… TwitterとFacebookを、俺からBANしました。 ...

2020年12月03日 · (2024年12月06日 更新) · 1 分 · もりゃき

Windowsベースのショートカット論考(1)Ctrl編

まずは、Windowsの「Ctrl」と組み合わせて使われる、一般的なショートカットを列挙しよう。 これは、Windows7のユーザーエクスペリエンスガイドラインから抜粋したものとなる。 ...

2020年01月06日 · (2024年12月06日 更新) · 1 分 · もりゃき

rdpまわり雑まとめ

結論:VNCよりRDP使っとけばよさそう。 ...

2019年11月26日 · (2024年12月06日 更新) · 1 分 · もりゃき