回答編集履歴

2

見直しキャンペーン中

2023/08/15 10:12

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -2,24 +2,23 @@
2
2
  > ViewModel側でStackPanelを保持したいです。
3
3
 
4
4
  MVVMではWindows Forms的な考え方は捨ててください。
5
- 「Windows Forms的な考え方」とは、
5
+ 「Windows Forms的な考え方」とは、↓のようなことです。
6
6
  > コードビハインドでは「spanel.Children.Add(textBlock);」のように書く
7
7
 
8
- のようなことです。
9
8
  まったく手法が違うので最初は頭の切り替えが大変なのですが、ここがWPFの肝ですし頑張ってください(WPFでもWindows Forms的にコードビハインドでガリガリ書くのを否定するつもりはありません)
10
9
 
11
10
  MVVMについては良記事がたくさんありますので、検索してください^^;
12
11
 
13
12
  ---
14
13
 
15
- 今回の目標は「StackPanelに動的にTextBlockを追加」ということですね。
14
+ 今回の目標は「`StackPanel`に動的に`TextBlock`を追加」ということですね。
16
15
 
17
16
  「`StackPanel`」ということは、アイテムが複数あるということです。
18
17
  そして「動的」ということは、アイテムの増減があるということです。
19
18
 
20
19
  この時点で、
21
- * `View`では`ItemsControl`(`ListBox`や`DataGrid`等も含む)を使う
20
+ * Viewでは`ItemsControl`(`ListBox`や`DataGrid`等も含む)を使う
22
- * `ViewModel`では`ObservableCollection`を使う
21
+ * ViewModelでは`ObservableCollection`を使う
23
22
 
24
23
  ことが確定します(もうそういうもんだと覚えてください^^;
25
24
 
@@ -27,7 +26,7 @@
27
26
 
28
27
  [ObservableCollection<T> クラス (System.Collections.ObjectModel) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.objectmodel.observablecollection-1?view=net-6.0)
29
28
 
30
- コードを見てもらったほうが早いですが、`ViewModel`では文字列のコレクションとして保持し、`View`でその文字列を`DataTemplate`で`TextBlock.Run`に展開する感じです^^
29
+ コードを見てもらったほうが早いですが、ViewModelでは文字列のコレクションとして保持し、Viewでその文字列を`DataTemplate`で`TextBlock.Run`に展開する感じです^^
31
30
 
32
31
 
33
32
  ```xml

1

見直しキャンペーン中

2023/07/29 13:59

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -1,235 +1,118 @@
1
1
  > StackPanelに動的にTextBlockを追加するため
2
-
3
2
  > ViewModel側でStackPanelを保持したいです。
4
3
 
5
-
6
-
7
4
  MVVMではWindows Forms的な考え方は捨ててください。
8
-
9
5
  「Windows Forms的な考え方」とは、
10
-
11
6
  > コードビハインドでは「spanel.Children.Add(textBlock);」のように書く
12
7
 
13
-
14
-
15
8
  のようなことです。
16
-
17
9
  まったく手法が違うので最初は頭の切り替えが大変なのですが、ここがWPFの肝ですし頑張ってください(WPFでもWindows Forms的にコードビハインドでガリガリ書くのを否定するつもりはありません)
18
-
19
-
20
10
 
21
11
  MVVMについては良記事がたくさんありますので、検索してください^^;
22
12
 
23
-
24
-
25
13
  ---
26
-
27
-
28
14
 
29
15
  今回の目標は「StackPanelに動的にTextBlockを追加」ということですね。
30
16
 
31
-
32
-
33
17
  「`StackPanel`」ということは、アイテムが複数あるということです。
34
-
35
18
  そして「動的」ということは、アイテムの増減があるということです。
36
19
 
37
-
38
-
39
20
  この時点で、
40
-
41
21
  * `View`では`ItemsControl`(`ListBox`や`DataGrid`等も含む)を使う
42
-
43
22
  * `ViewModel`では`ObservableCollection`を使う
44
-
45
-
46
23
 
47
24
  ことが確定します(もうそういうもんだと覚えてください^^;
48
25
 
49
-
50
-
51
26
  [ItemsControl 攻略 ~ 外観のカスタマイズ | grabacr.nét](http://grabacr.net/archives/1240)
52
27
 
53
-
54
-
55
28
  [ObservableCollection<T> クラス (System.Collections.ObjectModel) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.objectmodel.observablecollection-1?view=net-6.0)
56
-
57
-
58
29
 
59
30
  コードを見てもらったほうが早いですが、`ViewModel`では文字列のコレクションとして保持し、`View`でその文字列を`DataTemplate`で`TextBlock.Run`に展開する感じです^^
60
31
 
61
32
 
62
-
63
-
64
-
65
- ```xaml
33
+ ```xml
66
-
67
34
  <Window
68
-
69
35
  x:Class="Questions376475.MainWindow"
70
-
71
36
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
72
-
73
37
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
74
-
75
38
  xmlns:local="clr-namespace:Questions376475"
76
-
77
39
  Width="525"
78
-
79
40
  Height="350">
80
-
81
41
  <Window.DataContext>
82
-
83
42
  <local:ViewModel />
84
-
85
43
  </Window.DataContext>
86
-
87
44
  <DockPanel>
88
-
89
45
  <Label Content="{Binding TestLabel}" DockPanel.Dock="Top" />
90
46
 
91
-
92
-
93
47
  <Button
94
-
95
48
  Command="{Binding AddCommand}"
96
-
97
49
  Content="Add"
98
-
99
50
  DockPanel.Dock="Bottom" />
100
51
 
101
-
102
-
103
52
  <ItemsControl ItemsSource="{Binding ItemList}">
104
-
105
53
  <ItemsControl.ItemTemplate>
106
-
107
54
  <DataTemplate>
108
-
109
55
  <TextBlock>
110
-
111
56
  <Run Foreground="Red" Text="{Binding .}" />
112
-
113
57
  </TextBlock>
114
-
115
58
  <!--<TextBlock Foreground="Red" Text="{Binding .}" />-->
116
-
117
59
  </DataTemplate>
118
-
119
60
  </ItemsControl.ItemTemplate>
120
-
121
61
  </ItemsControl>
122
-
123
62
  </DockPanel>
124
-
125
63
  </Window>
126
-
127
64
  ```
128
65
 
129
-
130
-
131
- ```C#
66
+ ```cs
132
-
133
67
  using System.Collections.ObjectModel;
134
-
135
68
  using System.Windows;
136
-
137
69
  using CommunityToolkit.Mvvm.ComponentModel;
138
-
139
70
  using CommunityToolkit.Mvvm.Input;
140
71
 
141
-
142
-
143
72
  namespace Questions376475
144
-
145
73
  {
146
-
147
74
  public class ViewModel : ObservableObject // ViewModelBase
148
-
149
75
  {
150
-
151
76
  private string _testLabel = "初期値";
152
-
153
77
  public string TestLabel
154
-
155
78
  {
156
-
157
79
  get => _testLabel;
158
-
159
80
  set => SetProperty(ref _testLabel, value);
160
-
161
81
  }
162
82
 
163
-
164
-
165
83
  public ObservableCollection<string> ItemList { get; }
166
-
167
-
168
84
 
169
85
  public RelayCommand AddCommand { get; }
170
86
 
171
87
 
172
-
173
-
174
-
175
88
  public ViewModel()
176
-
177
89
  {
178
-
179
90
  ItemList = new ObservableCollection<string>
180
-
181
91
  {
182
-
183
92
  "テスト1",
184
-
185
93
  "テスト2",
186
-
187
94
  "テスト3",
188
-
189
95
  };
190
96
 
191
-
192
-
193
97
  AddCommand = new RelayCommand(Add);
194
-
195
98
  }
196
99
 
197
-
198
-
199
100
  private void Add()
200
-
201
101
  {
202
-
203
102
  ItemList.Add($"テスト{ItemList.Count + 1}");
204
103
 
205
-
206
-
207
104
  TestLabel = $"{ItemList.Count}個です";
208
-
209
105
  }
210
-
211
106
  }
212
107
 
213
-
214
-
215
108
  public partial class MainWindow : Window
216
-
217
109
  {
218
-
219
110
  public MainWindow() => InitializeComponent();
220
-
221
111
  }
222
-
223
112
  }
224
-
225
113
  ```
226
114
 
227
-
228
-
229
115
  `ViewModelBase`や`ICommand`実装を書くのがだるいので、下記を使用しました。
230
-
231
116
  [NuGet Gallery | CommunityToolkit.Mvvm 7.1.2](https://www.nuget.org/packages/CommunityToolkit.Mvvm/7.1.2)
232
117
 
233
-
234
-
235
118
  [Introduction to the MVVM Toolkit - Windows Community Toolkit | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/communitytoolkit/mvvm/introduction)