前提
MVVMで、Viewのボタンを押したらその後一定間隔で対象機へポーリングし、実行結果をViewへ通知するような仕組みを作ろうとしています。
※MVVM初心者。
MVVMでやるとなった場合に、どこでタイマーを稼働させるべきなのか(Command?Model?)、Modelだったとした場合はModelへ更にViewModelのインスタンスを渡すようにするのか、通常の実装方法が分かりませんでした。
※後者ではできそうだとは思っています。
解決したいこと
- 一般的にどう実装するものなのか、教えていただきたいです。
- どこでタイマーを稼働させるべきなのか(Command?Model?)
- Modelだったとした場合はModelへ更にViewModelのインスタンスを渡すようにするのか
補足情報(FW/ツールのバージョンなど)
VS2022 .NET6
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答1件
0
ベストアンサー
どこでタイマーを稼働させるべきなのか(Command?Model?)
それが一連の処理なら、ModelなりServiceなりになるんじゃないでしょうか(少なくともViewModelではないような)
Modelだったとした場合はModelへ更にViewModelのインスタンスを渡すようにするのか
MVVMでModelがViewModelを参照することはありません。
xml
1<Window 2 x:Class="Qu1hlld0oo83bby.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <StackPanel> 8 <Button Command="{Binding StartPollingCommand}" Content="StartPolling(連打可)" /> 9 <Button Command="{Binding StartPolling2Command}" Content="StartPolling2(連打不可)" /> 10 <TextBlock Text="{Binding Model.Result}" /> 11 12 <Button Command="{Binding GetResultCommand}" Content="GetResult(連打不可)" /> 13 <TextBlock Text="{Binding Result}" /> 14 </StackPanel> 15</Window>
cs
1using System; 2using System.Threading; 3using System.Threading.Tasks; 4using System.Windows; 5using CommunityToolkit.Mvvm.ComponentModel; 6using CommunityToolkit.Mvvm.Input; 7 8namespace Qu1hlld0oo83bby 9{ 10 // ModelがINotifyPropertyChangedを実装し変更通知する 11 public partial class Model : ObservableObject 12 { 13 [ObservableProperty] 14 // ↓がソースジェネレータで生成されています 15 //public string? Result { get => result; set => SetProperty(ref result, value); } 16 private string? result; 17 18 private int count; 19 20 public void StartPolling() 21 { 22 for (var i = 0; i < 20; i++) 23 { 24 Thread.Sleep(100); 25 } 26 27 Result = $"{count++}"; 28 } 29 } 30 31 // 結果を取得できればいいだけのようなイメージでService 32 public class Service 33 { 34 private int count; 35 36 public async Task<string> GetResultAsync() 37 { 38 for (var i = 0; i < 20; i++) 39 { 40 await Task.Delay(TimeSpan.FromMilliseconds(100)); 41 } 42 43 return $"{count++}"; 44 } 45 } 46 47 public partial class ViewModel : ObservableObject 48 { 49 public Model Model { get; } // ラップするのがめんどいので直公開w 50 51 [ObservableProperty] 52 private string? result; 53 54 private Service service; 55 56 public ViewModel(Model model, Service service) 57 { 58 Model = model; 59 this.service = service; 60 } 61 62 [RelayCommand] 63 // ↓がソースジェネレータで生成されています 64 //private RelayCommand? startPollingCommand; 65 //public IRelayCommand StartPollingCommand => startPollingCommand ??= new RelayCommand(StartPolling); 66 private void StartPolling() 67 { 68 Task.Run(() => Model.StartPolling()); // 投げっぱなし 69 } 70 71 [RelayCommand] 72 private async Task StartPolling2Async() 73 { 74 await Task.Run(() => Model.StartPolling()); 75 } 76 77 [RelayCommand] 78 private async Task GetResultAsync() 79 { 80 Result = await service.GetResultAsync(); 81 } 82 } 83 84 public partial class MainWindow : Window 85 { 86 public MainWindow() 87 { 88 InitializeComponent(); 89 90 DataContext = new ViewModel(new Model(), new Service()); 91 } 92 } 93}
NuGet Gallery | CommunityToolkit.Mvvm 8.0.0
MVVM Toolkit の概要 - .NET Community Toolkit | Microsoft Docs
タイミングが悪いことに、今現在VSがバグっていてエラーが出ますw(回避コードを追加してください)
CommunityToolKit.Mvvm source generators run twice on Visual Studio 17.2.6 · Issue #343 · CommunityToolkit/dotnet
.csproj
xml
1<Project Sdk="Microsoft.NET.Sdk"> 2 3 <PropertyGroup> 4 <OutputType>WinExe</OutputType> 5 <TargetFramework>net6.0-windows</TargetFramework> 6 <Nullable>enable</Nullable> 7 <UseWPF>true</UseWPF> 8 </PropertyGroup> 9 10 <ItemGroup> 11 <PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" /> 12 </ItemGroup> 13 14 <Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile"> 15 <!-- Work around https://github.com/dotnet/wpf/issues/6792 --> 16 17 <ItemGroup> 18 <FilteredAnalyzer Include="@(Analyzer->Distinct())" /> 19 <Analyzer Remove="@(Analyzer)" /> 20 <Analyzer Include="@(FilteredAnalyzer)" /> 21 </ItemGroup> 22 </Target> 23 24</Project>
この処理に「進捗報告する・キャンセル対応する」等があると、また話が変わってきます。
wpf iprogress - Google 検索
投稿2022/08/06 11:27
編集2022/08/06 11:36総合スコア10022
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/08/06 15:00 編集
2022/09/23 10:26 編集
2022/08/07 17:20