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

回答編集履歴

4

見直しキャンペーン中

2023/08/13 08:35

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -135,10 +135,10 @@
135
135
 
136
136
  ---
137
137
 
138
- 追記 `.NET Core 3.1`でのcsproj
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

見直しキャンペーン中

2023/07/25 13:11

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,155 +1,155 @@
1
- 私はアマチュアなので一般的な方法はわかりませんが、C# 9.0で[レコード型](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-9#record-types)が入ったことですしちょっとやってみました。
2
-
3
- * C# 9.0以上
4
- * `Prism`(面倒なのでDIしません)
5
- * `ReactiveProperty`(後片付けしてません)
6
-
7
- ```xaml
8
- <Window
9
- x:Class="Questions305906.Views.MainWindow"
10
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
11
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
12
- Width="525"
13
- Height="350">
14
- <DockPanel>
15
- <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
16
- <Button Command="{Binding AddCommand}" Content="アイテム追加" />
17
- <Button Command="{Binding DispCommand}" Content="モデル確認" />
18
- </StackPanel>
19
- <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
20
- <DataGrid.Columns>
21
- <DataGridTextColumn Binding="{Binding Id}" Header="ID" IsReadOnly="True" />
22
- <DataGridTextColumn Width="200" Binding="{Binding Name}" Header="名前" />
23
- <DataGridTextColumn Width="100" Binding="{Binding Price}" Header="値段" />
24
- </DataGrid.Columns>
25
- </DataGrid>
26
- </DockPanel>
27
- </Window>
28
- ```
29
-
30
- ```C#
31
- namespace Questions305906.Models
32
- {
33
- using System.Collections.ObjectModel;
34
- using System.Diagnostics;
35
- using System.Linq;
36
-
37
- public record ItemModel(int Id, string Name, int Price);
38
-
39
- public class Provider
40
- {
41
- public ReadOnlyObservableCollection<ItemModel> Items { get; }
42
- private readonly ObservableCollection<ItemModel> items;
43
-
44
- public Provider()
45
- {
46
- items = new()
47
- {
48
- new(Id: 1, Name: "aaa", Price: 123),
49
- new(Id: 2, Name: "bbbb", Price: 456),
50
- new(Id: 3, Name: "ccccc", Price: 7890),
51
- };
52
-
53
- Items = new(items);
54
- }
55
-
56
- public void Replace(ItemModel oldValue, ItemModel newValue)
57
- {
58
- var index = items.IndexOf(oldValue);
59
- items.Remove(oldValue);
60
- items.Insert(index, newValue);
61
- }
62
-
63
- public void Add()
64
- {
65
- var id = items.Max(x => x.Id) + 1;
66
- items.Add(new(Id: id, Name: "", Price: 0));
67
- }
68
-
69
- public void Disp()
70
- {
71
- foreach (var item in items) Debug.WriteLine(item);
72
- }
73
- }
74
- }
75
-
76
- namespace Questions305906.ViewModels
77
- {
78
- using Prism.Mvvm;
79
- using Questions305906.Models;
80
- using Reactive.Bindings;
81
- using Reactive.Bindings.Extensions;
82
- using System;
83
-
84
- public class ItemViewModel : BindableBase
85
- {
86
- public int Id { get; }
87
-
88
- private string _Name;
89
- public string Name { get => _Name; set => SetProperty(ref _Name, value); }
90
-
91
- private int _Price;
92
- public int Price { get => _Price; set => SetProperty(ref _Price, value); }
93
-
94
- internal ItemModel Item;
95
- internal ItemModel NewItem => Item = Item with { Name = Name, Price = Price };
96
-
97
-
98
- public ItemViewModel(ItemModel item) => (Item, Id, Name, Price) = (item, item.Id, item.Name, item.Price);
99
- }
100
-
101
- public class MainWindowViewModel : BindableBase
102
- {
103
- public ReadOnlyReactiveCollection<ItemViewModel> Items { get; }
104
- public ReactiveCommand AddCommand { get; } = new();
105
- public ReactiveCommand DispCommand { get; } = new();
106
-
107
- private readonly Provider provider = new();
108
-
109
-
110
- public MainWindowViewModel()
111
- {
112
- Items = provider.Items.ToReadOnlyReactiveCollection(x => new ItemViewModel(x));
113
- Items.ObserveElementPropertyChanged().Subscribe(x => provider.Replace(x.Sender.Item, x.Sender.NewItem));
114
-
115
- AddCommand.Subscribe(() => provider.Add());
116
- DispCommand.Subscribe(() => provider.Disp());
117
- }
118
- }
119
- }
120
- // .NET5でない場合
121
- //namespace System.Runtime.CompilerServices
122
- //{
123
- // public class IsExternalInit { }
124
- //}
125
- ```
126
- 同値があるとおかしくなるのは目に見えているので、`Id`をユニークにしました。
127
- `DataGrid`のプレースホルダも使用しませんでした(方法はありそうですが未調査)
128
-
129
-
130
- 結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです(`M`→`VM`の詰め替え・`Provider.Items`の入れ替え、どちらも)
131
- しかしこれは筋がいいとは思えないです(`NewItem`の雑さ^^;
132
-
133
- レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^
134
-
135
-
136
- ---
137
-
138
- 追記 `.NET Core 3.1`でのcsproj
139
- ↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください。
140
-
141
- ```xml
142
- <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
143
- <PropertyGroup>
144
- <OutputType>WinExe</OutputType>
145
- <TargetFramework>netcoreapp3.1</TargetFramework>
146
- <UseWPF>true</UseWPF>
147
- <AssemblyName>Questions305906</AssemblyName>
148
- <LangVersion>9.0</LangVersion>
149
- </PropertyGroup>
150
- <ItemGroup>
151
- <PackageReference Include="Prism.DryIoc" Version="8.0.0.1909" />
152
- <PackageReference Include="ReactiveProperty" Version="7.5.1" />
153
- </ItemGroup>
154
- </Project>
1
+ 私はアマチュアなので一般的な方法はわかりませんが、C# 9.0で[レコード型](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-9#record-types)が入ったことですしちょっとやってみました。
2
+
3
+ * C# 9.0以上
4
+ * `Prism`(面倒なのでDIしません)
5
+ * `ReactiveProperty`(後片付けしてません)
6
+
7
+ ```xml
8
+ <Window
9
+ x:Class="Questions305906.Views.MainWindow"
10
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
11
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
12
+ Width="525"
13
+ Height="350">
14
+ <DockPanel>
15
+ <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
16
+ <Button Command="{Binding AddCommand}" Content="アイテム追加" />
17
+ <Button Command="{Binding DispCommand}" Content="モデル確認" />
18
+ </StackPanel>
19
+ <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}">
20
+ <DataGrid.Columns>
21
+ <DataGridTextColumn Binding="{Binding Id}" Header="ID" IsReadOnly="True" />
22
+ <DataGridTextColumn Width="200" Binding="{Binding Name}" Header="名前" />
23
+ <DataGridTextColumn Width="100" Binding="{Binding Price}" Header="値段" />
24
+ </DataGrid.Columns>
25
+ </DataGrid>
26
+ </DockPanel>
27
+ </Window>
28
+ ```
29
+
30
+ ```cs
31
+ namespace Questions305906.Models
32
+ {
33
+ using System.Collections.ObjectModel;
34
+ using System.Diagnostics;
35
+ using System.Linq;
36
+
37
+ public record ItemModel(int Id, string Name, int Price);
38
+
39
+ public class Provider
40
+ {
41
+ public ReadOnlyObservableCollection<ItemModel> Items { get; }
42
+ private readonly ObservableCollection<ItemModel> items;
43
+
44
+ public Provider()
45
+ {
46
+ items = new()
47
+ {
48
+ new(Id: 1, Name: "aaa", Price: 123),
49
+ new(Id: 2, Name: "bbbb", Price: 456),
50
+ new(Id: 3, Name: "ccccc", Price: 7890),
51
+ };
52
+
53
+ Items = new(items);
54
+ }
55
+
56
+ public void Replace(ItemModel oldValue, ItemModel newValue)
57
+ {
58
+ var index = items.IndexOf(oldValue);
59
+ items.Remove(oldValue);
60
+ items.Insert(index, newValue);
61
+ }
62
+
63
+ public void Add()
64
+ {
65
+ var id = items.Max(x => x.Id) + 1;
66
+ items.Add(new(Id: id, Name: "", Price: 0));
67
+ }
68
+
69
+ public void Disp()
70
+ {
71
+ foreach (var item in items) Debug.WriteLine(item);
72
+ }
73
+ }
74
+ }
75
+
76
+ namespace Questions305906.ViewModels
77
+ {
78
+ using Prism.Mvvm;
79
+ using Questions305906.Models;
80
+ using Reactive.Bindings;
81
+ using Reactive.Bindings.Extensions;
82
+ using System;
83
+
84
+ public class ItemViewModel : BindableBase
85
+ {
86
+ public int Id { get; }
87
+
88
+ private string _Name;
89
+ public string Name { get => _Name; set => SetProperty(ref _Name, value); }
90
+
91
+ private int _Price;
92
+ public int Price { get => _Price; set => SetProperty(ref _Price, value); }
93
+
94
+ internal ItemModel Item;
95
+ internal ItemModel NewItem => Item = Item with { Name = Name, Price = Price };
96
+
97
+
98
+ public ItemViewModel(ItemModel item) => (Item, Id, Name, Price) = (item, item.Id, item.Name, item.Price);
99
+ }
100
+
101
+ public class MainWindowViewModel : BindableBase
102
+ {
103
+ public ReadOnlyReactiveCollection<ItemViewModel> Items { get; }
104
+ public ReactiveCommand AddCommand { get; } = new();
105
+ public ReactiveCommand DispCommand { get; } = new();
106
+
107
+ private readonly Provider provider = new();
108
+
109
+
110
+ public MainWindowViewModel()
111
+ {
112
+ Items = provider.Items.ToReadOnlyReactiveCollection(x => new ItemViewModel(x));
113
+ Items.ObserveElementPropertyChanged().Subscribe(x => provider.Replace(x.Sender.Item, x.Sender.NewItem));
114
+
115
+ AddCommand.Subscribe(() => provider.Add());
116
+ DispCommand.Subscribe(() => provider.Disp());
117
+ }
118
+ }
119
+ }
120
+ // .NET5でない場合
121
+ //namespace System.Runtime.CompilerServices
122
+ //{
123
+ // public class IsExternalInit { }
124
+ //}
125
+ ```
126
+ 同値があるとおかしくなるのは目に見えているので、`Id`をユニークにしました。
127
+ `DataGrid`のプレースホルダも使用しませんでした(方法はありそうですが未調査)
128
+
129
+
130
+ 結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです(`M`→`VM`の詰め替え・`Provider.Items`の入れ替え、どちらも)
131
+ しかしこれは筋がいいとは思えないです(`NewItem`の雑さ^^;
132
+
133
+ レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^
134
+
135
+
136
+ ---
137
+
138
+ 追記 `.NET Core 3.1`でのcsproj
139
+ ↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください。
140
+
141
+ ```xml
142
+ <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
143
+ <PropertyGroup>
144
+ <OutputType>WinExe</OutputType>
145
+ <TargetFramework>netcoreapp3.1</TargetFramework>
146
+ <UseWPF>true</UseWPF>
147
+ <AssemblyName>Questions305906</AssemblyName>
148
+ <LangVersion>9.0</LangVersion>
149
+ </PropertyGroup>
150
+ <ItemGroup>
151
+ <PackageReference Include="Prism.DryIoc" Version="8.0.0.1909" />
152
+ <PackageReference Include="ReactiveProperty" Version="7.5.1" />
153
+ </ItemGroup>
154
+ </Project>
155
155
  ```

2

.NET Core 3.1でのcsproj

2020/11/26 08:45

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -130,4 +130,26 @@
130
130
  結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです(`M`→`VM`の詰め替え・`Provider.Items`の入れ替え、どちらも)
131
131
  しかしこれは筋がいいとは思えないです(`NewItem`の雑さ^^;
132
132
 
133
- レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^
133
+ レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^
134
+
135
+
136
+ ---
137
+
138
+ 追記 `.NET Core 3.1`でのcsproj
139
+ ↑提示コードの最下段`System.Runtime.CompilerServices.IsExternalInit`のコメントを外してください。
140
+
141
+ ```xml
142
+ <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
143
+ <PropertyGroup>
144
+ <OutputType>WinExe</OutputType>
145
+ <TargetFramework>netcoreapp3.1</TargetFramework>
146
+ <UseWPF>true</UseWPF>
147
+ <AssemblyName>Questions305906</AssemblyName>
148
+ <LangVersion>9.0</LangVersion>
149
+ </PropertyGroup>
150
+ <ItemGroup>
151
+ <PackageReference Include="Prism.DryIoc" Version="8.0.0.1909" />
152
+ <PackageReference Include="ReactiveProperty" Version="7.5.1" />
153
+ </ItemGroup>
154
+ </Project>
155
+ ```

1

正しくはC# 9.0以上ですね^^;

2020/11/26 08:45

投稿

TN8001
TN8001

スコア10111

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  私はアマチュアなので一般的な方法はわかりませんが、C# 9.0で[レコード型](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-9#record-types)が入ったことですしちょっとやってみました。
2
2
 
3
- * `.NET 5.0`以上
3
+ * C# 9.0以上
4
4
  * `Prism`(面倒なのでDIしません)
5
5
  * `ReactiveProperty`(後片付けしてません)
6
6
 
@@ -117,12 +117,17 @@
117
117
  }
118
118
  }
119
119
  }
120
+ // .NET5でない場合
121
+ //namespace System.Runtime.CompilerServices
122
+ //{
123
+ // public class IsExternalInit { }
124
+ //}
120
125
  ```
121
126
  同値があるとおかしくなるのは目に見えているので、`Id`をユニークにしました。
122
127
  `DataGrid`のプレースホルダも使用しませんでした(方法はありそうですが未調査)
123
128
 
124
129
 
125
- 結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです
130
+ 結局どうにかして詰め替えるしかないわけですが、`ReactiveProperty`のおかげでそれほど面倒というわけでもなかったです(`M`→`VM`の詰め替え・`Provider.Items`の入れ替え、どちらも)
126
131
  しかしこれは筋がいいとは思えないです(`NewItem`の雑さ^^;
127
132
 
128
133
  レコード型が浸透してきてライブラリ等のサポートが入ってくれば、また変わると思います。まあこれからですね^^