質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

5897閲覧

[WPF][MVVM] MVVMで定期的に処理を行う方法について

WTB_21

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

0クリップ

投稿2020/06/30 08:52

ViewModelで定期的に動作する処理を実装したい

定期的に動作する処理の実装を行いたいと考えております。
コードビハインドでDispatcherTimerを使用することにより実装することが出来ましたが、
MVVMではコードビハインドに書くことは推奨されないとのことですのでMVVMに則った
実装方法についてご教授いただけないでしょうか。

実装したコード

View

XAML

1<Window x:Class="DispatcherTimerTest.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 Title="MainWindow" Height="450" Width="800"> 8 <Grid> 9 <Label Content="{Binding LabelContent}"/> 10 </Grid> 11</Window>

C#

1 public partial class MainWindow : Window 2 { 3 public System.Windows.Threading.DispatcherTimer dispatcherTimer; 4 5 public MainWindow() 6 { 7 InitializeComponent(); 8 DataContext = ViewModel.Instance; 9 dispatcherTimer = new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Normal); 10 dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 100); 11 dispatcherTimer.Tick += DispatcherTimer_Tick; 12 dispatcherTimer.Start(); 13 14 } 15 16 ~MainWindow() 17 { 18 dispatcherTimer.Stop(); 19 } 20 21 private void DispatcherTimer_Tick(object sender, EventArgs e) 22 { 23 ViewModel.Instance.LabelContent += 1; 24 } 25 }

ViewModel

C#

1 class ViewModel : INotifyPropertyChanged 2 { 3 public static ViewModel Instance { get; } = new ViewModel(); 4 5 public event PropertyChangedEventHandler PropertyChanged; 6 protected void OnPropertyChanged(string name) 7 { 8 if (PropertyChanged != null) 9 { 10 PropertyChanged(this, new PropertyChangedEventArgs(name)); 11 } 12 } 13 14 public int LabelContent 15 { 16 get { return _LabelContent; } 17 set 18 { 19 _LabelContent = value; 20 OnPropertyChanged(nameof(LabelContent)); 21 } 22 } 23 private int _LabelContent; 24 }
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ViewModelでDispatcherTimerを使ってはダメということはないので、単に移せばいいんじゃないでしょうか。

UIスレッドで動かす意味はないので、こちらなどでもいいでしょう。
Timer クラス (System.Timers) | Microsoft Docs
Timer クラス (System.Threading) | Microsoft Docs
こういったのもあります。
Observable.Timer Method (System.Reactive.Linq) | Microsoft Docs


追記 実装例
後片付け省略^^;
それぞれ同じ意味にしたつもりですが、間違ってたらすいません^^;

xml

1<Window 2 x:Class="DispatcherTimerTest.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:DispatcherTimerTest" 6 Width="800" 7 Height="450" 8 DataContext="{x:Static local:ViewModel.Instance}"> 9 <StackPanel> 10 <Label Content="{Binding LabelContent1}" /> 11 <Label Content="{Binding LabelContent2}" /> 12 <Label Content="{Binding LabelContent3}" /> 13 <Label Content="{Binding LabelContent4}" /> 14 </StackPanel> 15</Window>

cs

1using System; 2using System.ComponentModel; 3using System.Reactive.Linq; 4using System.Runtime.CompilerServices; 5 6namespace DispatcherTimerTest 7{ 8 public class ViewModel : INotifyPropertyChanged 9 { 10 public static ViewModel Instance { get; } = new ViewModel(); 11 12 13 public int LabelContent1 { get => _LabelContent1; set => Set(ref _LabelContent1, value); } 14 private int _LabelContent1; 15 16 public int LabelContent2 { get => _LabelContent2; set => Set(ref _LabelContent2, value); } 17 private int _LabelContent2; 18 19 public int LabelContent3 { get => _LabelContent3; set => Set(ref _LabelContent3, value); } 20 private int _LabelContent3; 21 22 public int LabelContent4 { get => _LabelContent4; set => Set(ref _LabelContent4, value); } 23 private int _LabelContent4; 24 25 private System.Windows.Threading.DispatcherTimer dispatcherTimer; 26 private System.Timers.Timer timersTimer; 27 private System.Threading.Timer threadingTimer; 28 private IDisposable observableTimer; 29 30 public ViewModel() 31 { 32 dispatcherTimer = new System.Windows.Threading.DispatcherTimer(); 33 dispatcherTimer.Interval = TimeSpan.FromMilliseconds(100); 34 dispatcherTimer.Tick += (s, e) => LabelContent1 += 1; 35 dispatcherTimer.Start(); 36 37 38 timersTimer = new System.Timers.Timer(100); 39 timersTimer.Elapsed += (s, e) => LabelContent2 += 1; 40 timersTimer.AutoReset = true; 41 timersTimer.Enabled = true; 42 43 44 threadingTimer = new System.Threading.Timer(x => LabelContent3 += 1, null, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100)); 45 46 47 // NuGet System.Reactive.Linq 48 observableTimer = Observable.Timer(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100)) 49 .Subscribe(_ => LabelContent4 += 1); 50 51 } 52 53 #region INotifyPropertyChanged 54 public event PropertyChangedEventHandler PropertyChanged; 55 protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) 56 { 57 if(Equals(storage, value)) return false; 58 59 storage = value; 60 OnPropertyChanged(propertyName); 61 return true; 62 } 63 protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 64 => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 65 #endregion 66 } 67}

投稿2020/06/30 09:24

編集2023/07/22 08:13
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

WTB_21

2020/06/30 13:31

DispatcherTimer の使い方だけでなく4パターンもの実装方法をご教授くださりありがとうございます。 余談ですが、各プロパティのOnPropertyChangedの実装方法が煩雑だと嘆いていたのですが、 サンプルで頂いたコードならすっきりと書くことが出来そうなので真似させて頂こうと思います。
WTB_21

2020/07/01 03:27

定石となっているのですね。ベースクラスを作成したいと思います。 ReactivePropertyについても調べてみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問