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

回答編集履歴

2

見直しキャンペーン中

2023/08/15 09:34

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -6,8 +6,7 @@
6
6
 
7
7
  [MVVM をリアクティブプログラミングで快適に ReactiveProperty オーバービュー 2020 年版 中編 - Qiita](https://qiita.com/okazuki/items/dae37c42776727e6c8a5#reactivecommand)
8
8
 
9
- `ReactiveCommand`(ReactivePropertyの`ICommand`実装)でもほぼ同じですが、現状Reactive要素がまったくないので
9
+ `ReactiveCommand`(ReactivePropertyの`ICommand`実装)でもほぼ同じですが、現状Reactive要素がまったくないので`DelegateCommand`(Prismの`ICommand`実装)でやりました。
10
- `DelegateCommand`(Prismの`ICommand`実装)でやりました。
11
10
 
12
11
  しかしこれではViewModelが`DataGrid`に依存しますしテストもしにくく、あまりメリットがない気がします。
13
12
  こうするぐらいならまだコードビハインドのほうがましだったと(個人的には)感じます。

1

見直しキャンペーン中

2023/07/29 13:15

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,183 +1,183 @@
1
- > Clickイベントの動作をViewModelで実現したいです。
2
-
3
- 「ボタンを押したらViewModelの何かの処理をする」ような場合は、コマンド(`ICommand`)を使います。
4
-
5
- [Commanding | Prism](https://prismlibrary.com/docs/commanding.html)
6
-
7
- [MVVM をリアクティブプログラミングで快適に ReactiveProperty オーバービュー 2020 年版 中編 - Qiita](https://qiita.com/okazuki/items/dae37c42776727e6c8a5#reactivecommand)
8
-
9
- `ReactiveCommand`(ReactivePropertyの`ICommand`実装)でもほぼ同じですが、現状Reactive要素がまったくないので
10
- `DelegateCommand`(Prismの`ICommand`実装)でやりました。
11
-
12
- しかしこれではViewModelが`DataGrid`に依存しますしテストもしにくく、あまりメリットがない気がします。
13
- こうするぐらいならまだコードビハインドのほうがましだったと(個人的には)感じます。
14
-
15
-
16
- > ScrollIntoViewの実装方法が知りたいです。
17
-
18
- 実装できていると思うんですが、↑の話を踏まえてMVVMでのよりよい実装って意味ですか?
19
-
20
- MVVM絶対主義者(コードビハインドを書いたら負け勢)は、`Behavior`とか`TriggerAction`とかでやるんですかね?(わたしは絶対主義者ではありません)
21
- 試しにやってみましたが、xamlが長くなっただけな気もします^^;
22
-
23
- ```xaml
24
- <Window
25
- x:Class="Questions375184.Views.MainWindow"
26
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
27
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
28
- xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
29
- xmlns:prism="http://prismlibrary.com/"
30
- xmlns:v="clr-namespace:Questions375184.Views"
31
- Title="{Binding Title}"
32
- Width="800"
33
- Height="600"
34
- prism:ViewModelLocator.AutoWireViewModel="True">
35
- <DockPanel>
36
- <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />-->
37
- <StackPanel DockPanel.Dock="Bottom" Orientation="Vertical">
38
- <Button Click="BtnTopLine_Click" Content="BtnTopLine_Click" />
39
- <Button Click="BtnLastLine_Click" Content="BtnLastLine_Click" />
40
-
41
- <Separator />
42
-
43
- <Button
44
- Command="{Binding ScrollTopCommand}"
45
- CommandParameter="{Binding ElementName=DataGrid1}"
46
- Content="ScrollTopCommand" />
47
- <Button
48
- Command="{Binding ScrollEndCommand}"
49
- CommandParameter="{Binding ElementName=DataGrid1}"
50
- Content="ScrollEndCommand" />
51
-
52
- <Separator />
53
-
54
- <Button Content="ScrollTopAction">
55
- <i:Interaction.Triggers>
56
- <i:EventTrigger EventName="Click">
57
- <v:ScrollTopAction TargetObject="{Binding ElementName=DataGrid1}" />
58
- </i:EventTrigger>
59
- </i:Interaction.Triggers>
60
- </Button>
61
- <Button Content="ScrollEndAction">
62
- <i:Interaction.Triggers>
63
- <i:EventTrigger EventName="Click">
64
- <v:ScrollEndAction TargetObject="{Binding ElementName=DataGrid1}" />
65
- </i:EventTrigger>
66
- </i:Interaction.Triggers>
67
- </Button>
68
- </StackPanel>
69
-
70
- <DataGrid
71
- Name="DataGrid1"
72
- IsReadOnly="True"
73
- ItemsSource="{Binding DataSource1}" />
74
- </DockPanel>
75
- </Window>
76
- ```
77
-
78
- ```C#
79
- using System.Windows;
80
- using Microsoft.Xaml.Behaviors;
81
- using System.Windows.Controls;
82
-
83
- namespace Questions375184.Views
84
- {
85
- public partial class MainWindow : Window
86
- {
87
- public MainWindow() => InitializeComponent();
88
-
89
- private void BtnTopLine_Click(object sender, RoutedEventArgs e)
90
- {
91
- DataGrid1.Focus();
92
- DataGrid1.ScrollIntoView(DataGrid1.Items[0]);
93
- }
94
-
95
- private void BtnLastLine_Click(object sender, RoutedEventArgs e)
96
- {
97
- DataGrid1.Focus();
98
- DataGrid1.ScrollIntoView(DataGrid1.Items[^1]);
99
- }
100
- }
101
-
102
- public class ScrollTopAction : TargetedTriggerAction<DataGrid>
103
- {
104
- protected override void Invoke(object parameter)
105
- {
106
- Target.Focus();
107
- Target.ScrollIntoView(Target.Items[0]);
108
- }
109
- }
110
-
111
- public class ScrollEndAction : TargetedTriggerAction<DataGrid>
112
- {
113
- protected override void Invoke(object parameter)
114
- {
115
- Target.Focus();
116
- Target.ScrollIntoView(Target.Items[^1]);
117
- }
118
- }
119
- }
120
- ```
121
-
122
- ```C#
123
- using System.Data;
124
- using System.Windows.Controls;
125
- using Prism.Commands;
126
- using Prism.Mvvm;
127
-
128
- namespace Questions375184.ViewModels
129
- {
130
- public class MainWindowViewModel : BindableBase
131
- {
132
- public string Title { get => _title; set => SetProperty(ref _title, value); }
133
- private string _title = "Prism Application";
134
-
135
- public DataTable DataSource1 { get => _dataSource1; set => SetProperty(ref _dataSource1, value); }
136
- private DataTable _dataSource1;
137
-
138
- public DelegateCommand<DataGrid> ScrollTopCommand { get; }
139
- public DelegateCommand<DataGrid> ScrollEndCommand { get; }
140
-
141
-
142
- public MainWindowViewModel()
143
- {
144
- var columnCount = 20;
145
- var rowCount = 20;
146
- var dt = new DataTable();
147
-
148
- for (var i = 0; i < columnCount; i++)
149
- {
150
- dt.Columns.Add($"Column{i}");
151
- }
152
-
153
- for (var i = 0; i < rowCount; i++)
154
- {
155
- var row = dt.NewRow();
156
- for (var k = 0; k < columnCount; k++)
157
- {
158
- row[k] = $"{i}-{k}";
159
- }
160
- dt.Rows.Add(row);
161
- }
162
-
163
- DataSource1 = dt;
164
-
165
-
166
- ScrollTopCommand = new DelegateCommand<DataGrid>(ScrollToTop);
167
- ScrollEndCommand = new DelegateCommand<DataGrid>(ScrollToEnd);
168
- }
169
-
170
- private void ScrollToTop(DataGrid dataGrid)
171
- {
172
- dataGrid.Focus();
173
- dataGrid.ScrollIntoView(dataGrid.Items[0]);
174
- }
175
-
176
- private void ScrollToEnd(DataGrid dataGrid)
177
- {
178
- dataGrid.Focus();
179
- dataGrid.ScrollIntoView(dataGrid.Items[^1]);
180
- }
181
- }
182
- }
1
+ > Clickイベントの動作をViewModelで実現したいです。
2
+
3
+ 「ボタンを押したらViewModelの何かの処理をする」ような場合は、コマンド(`ICommand`)を使います。
4
+
5
+ [Commanding | Prism](https://prismlibrary.com/docs/commanding.html)
6
+
7
+ [MVVM をリアクティブプログラミングで快適に ReactiveProperty オーバービュー 2020 年版 中編 - Qiita](https://qiita.com/okazuki/items/dae37c42776727e6c8a5#reactivecommand)
8
+
9
+ `ReactiveCommand`(ReactivePropertyの`ICommand`実装)でもほぼ同じですが、現状Reactive要素がまったくないので
10
+ `DelegateCommand`(Prismの`ICommand`実装)でやりました。
11
+
12
+ しかしこれではViewModelが`DataGrid`に依存しますしテストもしにくく、あまりメリットがない気がします。
13
+ こうするぐらいならまだコードビハインドのほうがましだったと(個人的には)感じます。
14
+
15
+
16
+ > ScrollIntoViewの実装方法が知りたいです。
17
+
18
+ 実装できていると思うんですが、↑の話を踏まえてMVVMでのよりよい実装って意味ですか?
19
+
20
+ MVVM絶対主義者(コードビハインドを書いたら負け勢)は、`Behavior`とか`TriggerAction`とかでやるんですかね?(わたしは絶対主義者ではありません)
21
+ 試しにやってみましたが、xamlが長くなっただけな気もします^^;
22
+
23
+ ```xml
24
+ <Window
25
+ x:Class="Questions375184.Views.MainWindow"
26
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
27
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
28
+ xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
29
+ xmlns:prism="http://prismlibrary.com/"
30
+ xmlns:v="clr-namespace:Questions375184.Views"
31
+ Title="{Binding Title}"
32
+ Width="800"
33
+ Height="600"
34
+ prism:ViewModelLocator.AutoWireViewModel="True">
35
+ <DockPanel>
36
+ <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />-->
37
+ <StackPanel DockPanel.Dock="Bottom" Orientation="Vertical">
38
+ <Button Click="BtnTopLine_Click" Content="BtnTopLine_Click" />
39
+ <Button Click="BtnLastLine_Click" Content="BtnLastLine_Click" />
40
+
41
+ <Separator />
42
+
43
+ <Button
44
+ Command="{Binding ScrollTopCommand}"
45
+ CommandParameter="{Binding ElementName=DataGrid1}"
46
+ Content="ScrollTopCommand" />
47
+ <Button
48
+ Command="{Binding ScrollEndCommand}"
49
+ CommandParameter="{Binding ElementName=DataGrid1}"
50
+ Content="ScrollEndCommand" />
51
+
52
+ <Separator />
53
+
54
+ <Button Content="ScrollTopAction">
55
+ <i:Interaction.Triggers>
56
+ <i:EventTrigger EventName="Click">
57
+ <v:ScrollTopAction TargetObject="{Binding ElementName=DataGrid1}" />
58
+ </i:EventTrigger>
59
+ </i:Interaction.Triggers>
60
+ </Button>
61
+ <Button Content="ScrollEndAction">
62
+ <i:Interaction.Triggers>
63
+ <i:EventTrigger EventName="Click">
64
+ <v:ScrollEndAction TargetObject="{Binding ElementName=DataGrid1}" />
65
+ </i:EventTrigger>
66
+ </i:Interaction.Triggers>
67
+ </Button>
68
+ </StackPanel>
69
+
70
+ <DataGrid
71
+ Name="DataGrid1"
72
+ IsReadOnly="True"
73
+ ItemsSource="{Binding DataSource1}" />
74
+ </DockPanel>
75
+ </Window>
76
+ ```
77
+
78
+ ```cs
79
+ using System.Windows;
80
+ using Microsoft.Xaml.Behaviors;
81
+ using System.Windows.Controls;
82
+
83
+ namespace Questions375184.Views
84
+ {
85
+ public partial class MainWindow : Window
86
+ {
87
+ public MainWindow() => InitializeComponent();
88
+
89
+ private void BtnTopLine_Click(object sender, RoutedEventArgs e)
90
+ {
91
+ DataGrid1.Focus();
92
+ DataGrid1.ScrollIntoView(DataGrid1.Items[0]);
93
+ }
94
+
95
+ private void BtnLastLine_Click(object sender, RoutedEventArgs e)
96
+ {
97
+ DataGrid1.Focus();
98
+ DataGrid1.ScrollIntoView(DataGrid1.Items[^1]);
99
+ }
100
+ }
101
+
102
+ public class ScrollTopAction : TargetedTriggerAction<DataGrid>
103
+ {
104
+ protected override void Invoke(object parameter)
105
+ {
106
+ Target.Focus();
107
+ Target.ScrollIntoView(Target.Items[0]);
108
+ }
109
+ }
110
+
111
+ public class ScrollEndAction : TargetedTriggerAction<DataGrid>
112
+ {
113
+ protected override void Invoke(object parameter)
114
+ {
115
+ Target.Focus();
116
+ Target.ScrollIntoView(Target.Items[^1]);
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ ```cs
123
+ using System.Data;
124
+ using System.Windows.Controls;
125
+ using Prism.Commands;
126
+ using Prism.Mvvm;
127
+
128
+ namespace Questions375184.ViewModels
129
+ {
130
+ public class MainWindowViewModel : BindableBase
131
+ {
132
+ public string Title { get => _title; set => SetProperty(ref _title, value); }
133
+ private string _title = "Prism Application";
134
+
135
+ public DataTable DataSource1 { get => _dataSource1; set => SetProperty(ref _dataSource1, value); }
136
+ private DataTable _dataSource1;
137
+
138
+ public DelegateCommand<DataGrid> ScrollTopCommand { get; }
139
+ public DelegateCommand<DataGrid> ScrollEndCommand { get; }
140
+
141
+
142
+ public MainWindowViewModel()
143
+ {
144
+ var columnCount = 20;
145
+ var rowCount = 20;
146
+ var dt = new DataTable();
147
+
148
+ for (var i = 0; i < columnCount; i++)
149
+ {
150
+ dt.Columns.Add($"Column{i}");
151
+ }
152
+
153
+ for (var i = 0; i < rowCount; i++)
154
+ {
155
+ var row = dt.NewRow();
156
+ for (var k = 0; k < columnCount; k++)
157
+ {
158
+ row[k] = $"{i}-{k}";
159
+ }
160
+ dt.Rows.Add(row);
161
+ }
162
+
163
+ DataSource1 = dt;
164
+
165
+
166
+ ScrollTopCommand = new DelegateCommand<DataGrid>(ScrollToTop);
167
+ ScrollEndCommand = new DelegateCommand<DataGrid>(ScrollToEnd);
168
+ }
169
+
170
+ private void ScrollToTop(DataGrid dataGrid)
171
+ {
172
+ dataGrid.Focus();
173
+ dataGrid.ScrollIntoView(dataGrid.Items[0]);
174
+ }
175
+
176
+ private void ScrollToEnd(DataGrid dataGrid)
177
+ {
178
+ dataGrid.Focus();
179
+ dataGrid.ScrollIntoView(dataGrid.Items[^1]);
180
+ }
181
+ }
182
+ }
183
183
  ```