回答編集履歴
4
見直しキャンペーン中
test
CHANGED
@@ -135,10 +135,10 @@
|
|
135
135
|
|
136
136
|
---
|
137
137
|
|
138
|
-
追記
|
138
|
+
追記
|
139
|
-
↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください
|
139
|
+
.NET Core 3.1でのcsproj(↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください)
|
140
140
|
|
141
|
-
```xml
|
141
|
+
```xml:.csproj
|
142
142
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
143
143
|
<PropertyGroup>
|
144
144
|
<OutputType>WinExe</OutputType>
|
3
見直しキャンペーン中
test
CHANGED
@@ -1,309 +1,155 @@
|
|
1
1
|
私はアマチュアなので一般的な方法はわかりませんが、C# 9.0で[レコード型](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-9#record-types)が入ったことですしちょっとやってみました。
|
2
2
|
|
3
|
-
|
4
|
-
|
5
3
|
* C# 9.0以上
|
6
|
-
|
7
4
|
* `Prism`(面倒なのでDIしません)
|
8
|
-
|
9
5
|
* `ReactiveProperty`(後片付けしてません)
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
```x
|
7
|
+
```xml
|
14
|
-
|
15
8
|
<Window
|
16
|
-
|
17
9
|
x:Class="Questions305906.Views.MainWindow"
|
18
|
-
|
19
10
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
20
|
-
|
21
11
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
22
|
-
|
23
12
|
Width="525"
|
24
|
-
|
25
13
|
Height="350">
|
26
|
-
|
27
14
|
<DockPanel>
|
28
|
-
|
29
15
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
30
|
-
|
31
16
|
<Button Command="{Binding AddCommand}" Content="アイテム追加" />
|
32
|
-
|
33
17
|
<Button Command="{Binding DispCommand}" Content="モデル確認" />
|
34
|
-
|
35
18
|
</StackPanel>
|
36
|
-
|
37
19
|
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
|
38
|
-
|
39
20
|
<DataGrid.Columns>
|
40
|
-
|
41
21
|
<DataGridTextColumn Binding="{Binding Id}" Header="ID" IsReadOnly="True" />
|
42
|
-
|
43
22
|
<DataGridTextColumn Width="200" Binding="{Binding Name}" Header="名前" />
|
44
|
-
|
45
23
|
<DataGridTextColumn Width="100" Binding="{Binding Price}" Header="値段" />
|
46
|
-
|
47
24
|
</DataGrid.Columns>
|
48
|
-
|
49
25
|
</DataGrid>
|
50
|
-
|
51
26
|
</DockPanel>
|
52
|
-
|
53
27
|
</Window>
|
54
|
-
|
55
28
|
```
|
56
29
|
|
57
|
-
|
58
|
-
|
59
|
-
```
|
30
|
+
```cs
|
60
|
-
|
61
31
|
namespace Questions305906.Models
|
62
|
-
|
63
32
|
{
|
64
|
-
|
65
33
|
using System.Collections.ObjectModel;
|
66
|
-
|
67
34
|
using System.Diagnostics;
|
68
|
-
|
69
35
|
using System.Linq;
|
70
|
-
|
71
|
-
|
72
36
|
|
73
37
|
public record ItemModel(int Id, string Name, int Price);
|
74
38
|
|
75
|
-
|
76
|
-
|
77
39
|
public class Provider
|
78
|
-
|
79
40
|
{
|
80
|
-
|
81
41
|
public ReadOnlyObservableCollection<ItemModel> Items { get; }
|
82
|
-
|
83
42
|
private readonly ObservableCollection<ItemModel> items;
|
84
43
|
|
85
|
-
|
86
|
-
|
87
44
|
public Provider()
|
88
|
-
|
89
45
|
{
|
90
|
-
|
91
46
|
items = new()
|
92
|
-
|
93
47
|
{
|
94
|
-
|
95
48
|
new(Id: 1, Name: "aaa", Price: 123),
|
96
|
-
|
97
49
|
new(Id: 2, Name: "bbbb", Price: 456),
|
98
|
-
|
99
50
|
new(Id: 3, Name: "ccccc", Price: 7890),
|
100
|
-
|
101
51
|
};
|
102
52
|
|
103
|
-
|
104
|
-
|
105
53
|
Items = new(items);
|
106
|
-
|
107
54
|
}
|
108
55
|
|
109
|
-
|
110
|
-
|
111
56
|
public void Replace(ItemModel oldValue, ItemModel newValue)
|
112
|
-
|
113
57
|
{
|
114
|
-
|
115
58
|
var index = items.IndexOf(oldValue);
|
116
|
-
|
117
59
|
items.Remove(oldValue);
|
118
|
-
|
119
60
|
items.Insert(index, newValue);
|
120
|
-
|
121
61
|
}
|
122
62
|
|
123
|
-
|
124
|
-
|
125
63
|
public void Add()
|
126
|
-
|
127
64
|
{
|
128
|
-
|
129
65
|
var id = items.Max(x => x.Id) + 1;
|
130
|
-
|
131
66
|
items.Add(new(Id: id, Name: "", Price: 0));
|
132
|
-
|
133
67
|
}
|
134
68
|
|
135
|
-
|
136
|
-
|
137
69
|
public void Disp()
|
138
|
-
|
139
70
|
{
|
140
|
-
|
141
71
|
foreach (var item in items) Debug.WriteLine(item);
|
142
|
-
|
143
72
|
}
|
144
|
-
|
145
73
|
}
|
146
|
-
|
147
74
|
}
|
148
75
|
|
149
|
-
|
150
|
-
|
151
76
|
namespace Questions305906.ViewModels
|
152
|
-
|
153
77
|
{
|
154
|
-
|
155
78
|
using Prism.Mvvm;
|
156
|
-
|
157
79
|
using Questions305906.Models;
|
158
|
-
|
159
80
|
using Reactive.Bindings;
|
160
|
-
|
161
81
|
using Reactive.Bindings.Extensions;
|
162
|
-
|
163
82
|
using System;
|
164
83
|
|
165
|
-
|
166
|
-
|
167
84
|
public class ItemViewModel : BindableBase
|
168
|
-
|
169
85
|
{
|
170
|
-
|
171
86
|
public int Id { get; }
|
172
87
|
|
173
|
-
|
174
|
-
|
175
88
|
private string _Name;
|
176
|
-
|
177
89
|
public string Name { get => _Name; set => SetProperty(ref _Name, value); }
|
178
90
|
|
179
|
-
|
180
|
-
|
181
91
|
private int _Price;
|
182
|
-
|
183
92
|
public int Price { get => _Price; set => SetProperty(ref _Price, value); }
|
184
93
|
|
185
|
-
|
186
|
-
|
187
94
|
internal ItemModel Item;
|
188
|
-
|
189
95
|
internal ItemModel NewItem => Item = Item with { Name = Name, Price = Price };
|
190
96
|
|
191
97
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
98
|
public ItemViewModel(ItemModel item) => (Item, Id, Name, Price) = (item, item.Id, item.Name, item.Price);
|
196
|
-
|
197
99
|
}
|
198
100
|
|
199
|
-
|
200
|
-
|
201
101
|
public class MainWindowViewModel : BindableBase
|
202
|
-
|
203
102
|
{
|
204
|
-
|
205
103
|
public ReadOnlyReactiveCollection<ItemViewModel> Items { get; }
|
206
|
-
|
207
104
|
public ReactiveCommand AddCommand { get; } = new();
|
208
|
-
|
209
105
|
public ReactiveCommand DispCommand { get; } = new();
|
210
|
-
|
211
|
-
|
212
106
|
|
213
107
|
private readonly Provider provider = new();
|
214
108
|
|
215
109
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
110
|
public MainWindowViewModel()
|
220
|
-
|
221
111
|
{
|
222
|
-
|
223
112
|
Items = provider.Items.ToReadOnlyReactiveCollection(x => new ItemViewModel(x));
|
224
|
-
|
225
113
|
Items.ObserveElementPropertyChanged().Subscribe(x => provider.Replace(x.Sender.Item, x.Sender.NewItem));
|
226
114
|
|
227
|
-
|
228
|
-
|
229
115
|
AddCommand.Subscribe(() => provider.Add());
|
230
|
-
|
231
116
|
DispCommand.Subscribe(() => provider.Disp());
|
232
|
-
|
233
117
|
}
|
234
|
-
|
235
118
|
}
|
236
|
-
|
237
119
|
}
|
238
|
-
|
239
120
|
// .NET5でない場合
|
240
|
-
|
241
121
|
//namespace System.Runtime.CompilerServices
|
242
|
-
|
243
122
|
//{
|
244
|
-
|
245
123
|
// public class IsExternalInit { }
|
246
|
-
|
247
124
|
//}
|
248
|
-
|
249
125
|
```
|
250
|
-
|
251
126
|
同値があるとおかしくなるのは目に見えているので、`Id`をユニークにしました。
|
252
|
-
|
253
127
|
`DataGrid`のプレースホルダも使用しませんでした(方法はありそうですが未調査)
|
254
128
|
|
255
129
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
130
|
結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです(`M`→`VM`の詰め替え・`Provider.Items`の入れ替え、どちらも)
|
260
|
-
|
261
131
|
しかしこれは筋がいいとは思えないです(`NewItem`の雑さ^^;
|
262
|
-
|
263
|
-
|
264
132
|
|
265
133
|
レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^
|
266
134
|
|
267
135
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
136
|
---
|
272
137
|
|
273
|
-
|
274
|
-
|
275
138
|
追記 `.NET Core 3.1`でのcsproj
|
276
|
-
|
277
139
|
↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください。
|
278
140
|
|
279
|
-
|
280
|
-
|
281
141
|
```xml
|
282
|
-
|
283
142
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
284
|
-
|
285
143
|
<PropertyGroup>
|
286
|
-
|
287
144
|
<OutputType>WinExe</OutputType>
|
288
|
-
|
289
145
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
290
|
-
|
291
146
|
<UseWPF>true</UseWPF>
|
292
|
-
|
293
147
|
<AssemblyName>Questions305906</AssemblyName>
|
294
|
-
|
295
148
|
<LangVersion>9.0</LangVersion>
|
296
|
-
|
297
149
|
</PropertyGroup>
|
298
|
-
|
299
150
|
<ItemGroup>
|
300
|
-
|
301
151
|
<PackageReference Include="Prism.DryIoc" Version="8.0.0.1909" />
|
302
|
-
|
303
152
|
<PackageReference Include="ReactiveProperty" Version="7.5.1" />
|
304
|
-
|
305
153
|
</ItemGroup>
|
306
|
-
|
307
154
|
</Project>
|
308
|
-
|
309
155
|
```
|
2
.NET Core 3.1でのcsproj
test
CHANGED
@@ -263,3 +263,47 @@
|
|
263
263
|
|
264
264
|
|
265
265
|
レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
|
270
|
+
|
271
|
+
---
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
追記 `.NET Core 3.1`でのcsproj
|
276
|
+
|
277
|
+
↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください。
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
```xml
|
282
|
+
|
283
|
+
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
284
|
+
|
285
|
+
<PropertyGroup>
|
286
|
+
|
287
|
+
<OutputType>WinExe</OutputType>
|
288
|
+
|
289
|
+
<TargetFramework>netcoreapp3.1</TargetFramework>
|
290
|
+
|
291
|
+
<UseWPF>true</UseWPF>
|
292
|
+
|
293
|
+
<AssemblyName>Questions305906</AssemblyName>
|
294
|
+
|
295
|
+
<LangVersion>9.0</LangVersion>
|
296
|
+
|
297
|
+
</PropertyGroup>
|
298
|
+
|
299
|
+
<ItemGroup>
|
300
|
+
|
301
|
+
<PackageReference Include="Prism.DryIoc" Version="8.0.0.1909" />
|
302
|
+
|
303
|
+
<PackageReference Include="ReactiveProperty" Version="7.5.1" />
|
304
|
+
|
305
|
+
</ItemGroup>
|
306
|
+
|
307
|
+
</Project>
|
308
|
+
|
309
|
+
```
|
1
正しくはC# 9.0以上ですね^^;
test
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
-
*
|
5
|
+
* C# 9.0以上
|
6
6
|
|
7
7
|
* `Prism`(面倒なのでDIしません)
|
8
8
|
|
@@ -236,6 +236,16 @@
|
|
236
236
|
|
237
237
|
}
|
238
238
|
|
239
|
+
// .NET5でない場合
|
240
|
+
|
241
|
+
//namespace System.Runtime.CompilerServices
|
242
|
+
|
243
|
+
//{
|
244
|
+
|
245
|
+
// public class IsExternalInit { }
|
246
|
+
|
247
|
+
//}
|
248
|
+
|
239
249
|
```
|
240
250
|
|
241
251
|
同値があるとおかしくなるのは目に見えているので、`Id`をユニークにしました。
|
@@ -246,7 +256,7 @@
|
|
246
256
|
|
247
257
|
|
248
258
|
|
249
|
-
結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです
|
259
|
+
結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです(`M`→`VM`の詰め替え・`Provider.Items`の入れ替え、どちらも)
|
250
260
|
|
251
261
|
しかしこれは筋がいいとは思えないです(`NewItem`の雑さ^^;
|
252
262
|
|