質問するログイン新規登録

回答編集履歴

1

見直しキャンペーン中

2023/07/26 13:57

投稿

TN8001
TN8001

スコア10180

answer CHANGED
@@ -1,102 +1,102 @@
1
- 基本的には重い処理を`Task.Run()`に包むだけです。
2
-
3
- > 「UI以外にセットさせると例外が発生する」
4
-
5
- UIスレッド以外からいじれないのはコントロール類です(`textBlock.Text=""`のような)
6
- バインディングに使用しているプロパティは、スレッドに関係なく変更できます。
7
-
8
- ```xaml
9
- <Window
10
- x:Class="MainWindow"
11
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
12
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
13
- xmlns:local="clr-namespace:Questions321254"
14
- Width="800"
15
- Height="450">
16
- <Window.DataContext>
17
- <local:ViewModel />
18
- </Window.DataContext>
19
- <DockPanel>
20
- <Menu DockPanel.Dock="Top">
21
- <MenuItem Command="{Binding MyCommand}" Header="MyCommand" />
22
- <MenuItem Command="{Binding MyCommand2}" Header="MyCommand2" />
23
- <MenuItem Command="{Binding AsyncReactiveCommand}" Header="AsyncReactiveCommand" />
24
- </Menu>
25
- <TextBlock Text="{Binding Output}" />
26
- </DockPanel>
27
- </Window>
28
- ```
29
-
30
- ```VB
31
- Imports System.Threading
32
- Imports Prism.Commands
33
- Imports Prism.Mvvm
34
- Imports Reactive.Bindings
35
-
36
- Public Class ViewModel
37
- Inherits BindableBase
38
-
39
- Private _Output As String
40
- Public Property Output As String
41
- Get
42
- Return _Output
43
- End Get
44
- Set(ByVal value As String)
45
- SetProperty(_Output, value)
46
- End Set
47
- End Property
48
-
49
- 'MyCommand2で実行可否に使用
50
- Private _CanExecute As Boolean = True
51
- Private Property CanExecute As Boolean
52
- Get
53
- Return _CanExecute
54
- End Get
55
- Set(ByVal value As Boolean)
56
- SetProperty(_CanExecute, value)
57
- End Set
58
- End Property
59
-
60
- Public ReadOnly Property MyCommand As DelegateCommand
61
- Public ReadOnly Property MyCommand2 As DelegateCommand
62
- Public ReadOnly Property AsyncReactiveCommand As AsyncReactiveCommand
63
-
64
- Public Sub New()
65
- MyCommand = New DelegateCommand(AddressOf MyCommandExecute)
66
- MyCommand2 = New DelegateCommand(Async Sub() Await MyCommand2Execute()).ObservesCanExecute(Function() CanExecute)
67
- AsyncReactiveCommand = New AsyncReactiveCommand().WithSubscribe(AddressOf AsyncReactiveCommandExecute)
68
- End Sub
69
-
70
- '何の制御もないので連打できてしまう
71
- Private Sub MyCommandExecute()
72
- Task.Run(Sub() HeavyWork()) '投げっぱなしTask
73
- End Sub
74
-
75
- '処理中は押せないようにCanExecuteプロパティで制御
76
- Private Async Function MyCommand2Execute() As Task
77
- CanExecute = False
78
- Await Task.Run(Sub() HeavyWork())
79
- CanExecute = True
80
- End Function
81
-
82
- 'AsyncReactiveCommandならおまかせできる
83
- Private Async Function AsyncReactiveCommandExecute() As Task
84
- Await Task.Run(Sub() HeavyWork())
85
- End Function
86
-
87
- Private Sub HeavyWork()
88
- Output += "はじめるよ" & vbLf
89
- Thread.Sleep(1000)
90
- Output += "もうちょっと" & vbLf
91
- Thread.Sleep(1000)
92
- Output += "おわったよ" & vbLf
93
- End Sub
94
- End Class
95
- ```
96
- VBは全然わかっていないので、変な書き方をしていたらすいません。
97
-
98
- `DelegateCommand`実装は↓を使用しました。
99
- [NuGet Gallery | Prism.Core 8.0.0.1909](https://www.nuget.org/packages/Prism.Core/)
100
-
101
- おまかせ例の`AsyncReactiveCommand`は↓に含まれています。
1
+ 基本的には重い処理を`Task.Run()`に包むだけです。
2
+
3
+ > 「UI以外にセットさせると例外が発生する」
4
+
5
+ UIスレッド以外からいじれないのはコントロール類です(`textBlock.Text=""`のような)
6
+ バインディングに使用しているプロパティは、スレッドに関係なく変更できます。
7
+
8
+ ```xml
9
+ <Window
10
+ x:Class="MainWindow"
11
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
12
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
13
+ xmlns:local="clr-namespace:Questions321254"
14
+ Width="800"
15
+ Height="450">
16
+ <Window.DataContext>
17
+ <local:ViewModel />
18
+ </Window.DataContext>
19
+ <DockPanel>
20
+ <Menu DockPanel.Dock="Top">
21
+ <MenuItem Command="{Binding MyCommand}" Header="MyCommand" />
22
+ <MenuItem Command="{Binding MyCommand2}" Header="MyCommand2" />
23
+ <MenuItem Command="{Binding AsyncReactiveCommand}" Header="AsyncReactiveCommand" />
24
+ </Menu>
25
+ <TextBlock Text="{Binding Output}" />
26
+ </DockPanel>
27
+ </Window>
28
+ ```
29
+
30
+ ```vb
31
+ Imports System.Threading
32
+ Imports Prism.Commands
33
+ Imports Prism.Mvvm
34
+ Imports Reactive.Bindings
35
+
36
+ Public Class ViewModel
37
+ Inherits BindableBase
38
+
39
+ Private _Output As String
40
+ Public Property Output As String
41
+ Get
42
+ Return _Output
43
+ End Get
44
+ Set(ByVal value As String)
45
+ SetProperty(_Output, value)
46
+ End Set
47
+ End Property
48
+
49
+ 'MyCommand2で実行可否に使用
50
+ Private _CanExecute As Boolean = True
51
+ Private Property CanExecute As Boolean
52
+ Get
53
+ Return _CanExecute
54
+ End Get
55
+ Set(ByVal value As Boolean)
56
+ SetProperty(_CanExecute, value)
57
+ End Set
58
+ End Property
59
+
60
+ Public ReadOnly Property MyCommand As DelegateCommand
61
+ Public ReadOnly Property MyCommand2 As DelegateCommand
62
+ Public ReadOnly Property AsyncReactiveCommand As AsyncReactiveCommand
63
+
64
+ Public Sub New()
65
+ MyCommand = New DelegateCommand(AddressOf MyCommandExecute)
66
+ MyCommand2 = New DelegateCommand(Async Sub() Await MyCommand2Execute()).ObservesCanExecute(Function() CanExecute)
67
+ AsyncReactiveCommand = New AsyncReactiveCommand().WithSubscribe(AddressOf AsyncReactiveCommandExecute)
68
+ End Sub
69
+
70
+ '何の制御もないので連打できてしまう
71
+ Private Sub MyCommandExecute()
72
+ Task.Run(Sub() HeavyWork()) '投げっぱなしTask
73
+ End Sub
74
+
75
+ '処理中は押せないようにCanExecuteプロパティで制御
76
+ Private Async Function MyCommand2Execute() As Task
77
+ CanExecute = False
78
+ Await Task.Run(Sub() HeavyWork())
79
+ CanExecute = True
80
+ End Function
81
+
82
+ 'AsyncReactiveCommandならおまかせできる
83
+ Private Async Function AsyncReactiveCommandExecute() As Task
84
+ Await Task.Run(Sub() HeavyWork())
85
+ End Function
86
+
87
+ Private Sub HeavyWork()
88
+ Output += "はじめるよ" & vbLf
89
+ Thread.Sleep(1000)
90
+ Output += "もうちょっと" & vbLf
91
+ Thread.Sleep(1000)
92
+ Output += "おわったよ" & vbLf
93
+ End Sub
94
+ End Class
95
+ ```
96
+ VBは全然わかっていないので、変な書き方をしていたらすいません。
97
+
98
+ `DelegateCommand`実装は↓を使用しました。
99
+ [NuGet Gallery | Prism.Core 8.0.0.1909](https://www.nuget.org/packages/Prism.Core/)
100
+
101
+ おまかせ例の`AsyncReactiveCommand`は↓に含まれています。
102
102
  [NuGet Gallery | ReactiveProperty 7.7.0](https://www.nuget.org/packages/ReactiveProperty/)