回答編集履歴

1

サンプル追加

2023/08/28 15:19

投稿

TN8001
TN8001

スコア9363

test CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  ViewModelで`UserControl`自体を保持してしまうと、テストしづらくMVVMのメリットがありません(というかViewとViewModelが分離できておらずMVVMになっていません)
24
24
 
25
- VBできないのでこれと言ってサンプル提示もできませんが^^;
25
+ ~~VBできないのでこれと言ってサンプル提示もできませんが^^;~~
26
26
 
27
27
  ---
28
28
 
@@ -33,3 +33,238 @@
33
33
 
34
34
  ぐちゃぐちゃマージン(`Margin="80,185,0,225"`のような)があると、ウィンドウリサイズ等で盛大に崩れます。
35
35
  `Grid`や`DockPanel`等を使ってちゃんとレイアウトしましょう。
36
+
37
+ ---
38
+
39
+ ざっとサンプル作りました(C#からの機械翻訳なので変なところがあるかもしれません)
40
+ が、遷移コマンドを子ViewModel内に用意するのは、ちょっと気持ち悪い気がします^^;
41
+ 個人的には`NavigationRail`(`TabControl`)や`DrawerHost`等を使って、こういった遷移にならないようにするほうが好みです^^
42
+
43
+ ```xml:MainWindow.xaml
44
+ <Window
45
+ x:Class="MainWindow"
46
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
47
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
48
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
49
+ xmlns:local="clr-namespace:Qoa07su5ulvykbq"
50
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
51
+ Title="MainWindow"
52
+ Width="800"
53
+ Height="450"
54
+ mc:Ignorable="d">
55
+ <Window.Resources>
56
+ <DataTemplate DataType="{x:Type local:UserControl1ViewModel}">
57
+ <local:UserControl1 />
58
+ </DataTemplate>
59
+ <DataTemplate DataType="{x:Type local:UserControl2ViewModel}">
60
+ <local:UserControl2 />
61
+ </DataTemplate>
62
+ </Window.Resources>
63
+ <Grid>
64
+ <ContentControl Content="{Binding CurrentView}" />
65
+ </Grid>
66
+ </Window>
67
+ ```
68
+ ```xml:UserControl1.xaml
69
+ <UserControl
70
+ x:Class="UserControl1"
71
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
72
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
73
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
74
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
75
+ d:DesignHeight="450"
76
+ d:DesignWidth="800"
77
+ Background="White"
78
+ mc:Ignorable="d">
79
+ <DockPanel>
80
+ <Grid DockPanel.Dock="Top">
81
+ <TextBlock
82
+ Background="#7F673AB7"
83
+ FontSize="24"
84
+ Foreground="White"
85
+ Text="UserControl1" />
86
+ <Button
87
+ Margin="8,4"
88
+ HorizontalAlignment="Right"
89
+ Command="{Binding SettingButtonCommand}"
90
+ Content="設定" />
91
+
92
+ <!-- こうやればコマンドをもらわずに済むがこれはこれで気持ち悪い^^; -->
93
+ <!--<Button
94
+ Margin="8,4"
95
+ HorizontalAlignment="Right"
96
+ Command="{Binding DataContext.GoToUserControl2Command, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
97
+ Content="設定" />-->
98
+ </Grid>
99
+
100
+ <Grid Margin="80,20,80,40">
101
+ <Grid.RowDefinitions>
102
+ <RowDefinition Height="Auto" />
103
+ <RowDefinition />
104
+ </Grid.RowDefinitions>
105
+ <DockPanel TextBlock.FontSize="24">
106
+ <Label VerticalAlignment="Center" Content="ロット番号" />
107
+ <TextBox
108
+ MinWidth="310"
109
+ MinHeight="64"
110
+ HorizontalAlignment="Left"
111
+ Style="{DynamicResource MaterialDesignOutlinedTextBox}"
112
+ Text="{Binding LotNumber, UpdateSourceTrigger=PropertyChanged}" />
113
+ </DockPanel>
114
+
115
+ <DockPanel Grid.Row="1" Margin="0,60,0,0">
116
+ <Label
117
+ Content="メッセージ"
118
+ DockPanel.Dock="Top"
119
+ FontSize="24" />
120
+ <TextBlock
121
+ Background="#19000000"
122
+ FontSize="48"
123
+ Style="{StaticResource MaterialDesignHeadline1TextBlock}" />
124
+ </DockPanel>
125
+ </Grid>
126
+ </DockPanel>
127
+ </UserControl>
128
+ ```
129
+ ```xml:UserControl2.xaml
130
+ <UserControl
131
+ x:Class="UserControl2"
132
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
133
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
134
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
135
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
136
+ d:DesignHeight="450"
137
+ d:DesignWidth="800"
138
+ Background="White"
139
+ mc:Ignorable="d">
140
+ <DockPanel>
141
+ <Grid DockPanel.Dock="Top">
142
+ <TextBlock
143
+ Background="#7F673AB7"
144
+ FontSize="24"
145
+ Foreground="White"
146
+ Text="UserControl2" />
147
+ <Button
148
+ Margin="8,4"
149
+ HorizontalAlignment="Right"
150
+ Command="{Binding BackButtonCommand}"
151
+ Content="戻る" />
152
+ </Grid>
153
+
154
+ <TextBox
155
+ Margin="80,20,80,40"
156
+ VerticalAlignment="Top"
157
+ FontSize="24"
158
+ Style="{DynamicResource MaterialDesignOutlinedTextBox}"
159
+ Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" />
160
+ </DockPanel>
161
+ </UserControl>
162
+ ```
163
+ ```vb
164
+ Imports System.ComponentModel.DataAnnotations
165
+ Imports CommunityToolkit.Mvvm.ComponentModel
166
+ Imports CommunityToolkit.Mvvm.Input
167
+
168
+ Public Class MainWindowViewModel
169
+ Inherits ObservableObject
170
+
171
+ Public Property CurrentView As Object
172
+ Get
173
+ Return _currentView
174
+ End Get
175
+ Set(ByVal value As Object)
176
+ SetProperty(_currentView, value)
177
+ End Set
178
+ End Property
179
+ Private _currentView As Object
180
+
181
+ Public ReadOnly Property GoToUserControl1Command As ICommand
182
+ Public ReadOnly Property GoToUserControl2Command As ICommand
183
+
184
+ Private userControl2ViewModel As UserControl2ViewModel
185
+
186
+ Public Sub New()
187
+ GoToUserControl1Command = New RelayCommand(AddressOf BackButton_Click)
188
+ GoToUserControl2Command = New RelayCommand(AddressOf SettingButton_Click)
189
+
190
+ '遷移させるのはこっちなのでコマンドを差し込み(ちょっと気持ち悪いか?^^;
191
+ CurrentView = New UserControl1ViewModel(GoToUserControl2Command)
192
+ userControl2ViewModel = New UserControl2ViewModel(GoToUserControl1Command)
193
+ End Sub
194
+
195
+ Private Sub SettingButton_Click()
196
+ 'インスタンス使いまわし(なのでTextの状態が残る)
197
+ CurrentView = userControl2ViewModel
198
+ End Sub
199
+
200
+ Private Sub BackButton_Click()
201
+ 'インスタンス都度生成(なのでLotNumberの状態は残らない)
202
+ CurrentView = New UserControl1ViewModel(GoToUserControl2Command)
203
+ End Sub
204
+ End Class
205
+
206
+ Public Class UserControl1ViewModel
207
+ Inherits ObservableValidator
208
+
209
+ <MaxLength(16, ErrorMessage:="最大16文字までです。")>
210
+ <RegularExpression("[a-zA-Z0-9]+", ErrorMessage:="半角英数字のみ入力できます。")>
211
+ Public Property LotNumber As String
212
+ Get
213
+ Return _lotNumber
214
+ End Get
215
+ Set(ByVal value As String)
216
+ SetProperty(_lotNumber, value, True)
217
+ End Set
218
+ End Property
219
+ Private _lotNumber As String
220
+
221
+ Public Property Message As String
222
+ Get
223
+ Return _message
224
+ End Get
225
+ Set(ByVal value As String)
226
+ SetProperty(_message, value)
227
+ End Set
228
+ End Property
229
+ Private _message As String
230
+
231
+ Public ReadOnly Property SettingButtonCommand As ICommand
232
+
233
+ Public Sub New(ByVal settingButtonCommand As ICommand)
234
+ Me.SettingButtonCommand = settingButtonCommand
235
+ End Sub
236
+ End Class
237
+
238
+ Public Class UserControl2ViewModel
239
+ Inherits ObservableObject
240
+
241
+ Public Property Text As String
242
+ Get
243
+ Return _text
244
+ End Get
245
+ Set(ByVal value As String)
246
+ SetProperty(_text, value, True)
247
+ End Set
248
+ End Property
249
+ Private _text As String
250
+
251
+ Public ReadOnly Property BackButtonCommand As ICommand
252
+
253
+ Public Sub New(ByVal backButtonCommand As ICommand)
254
+ Me.BackButtonCommand = backButtonCommand
255
+ End Sub
256
+ End Class
257
+
258
+ Partial Public Class MainWindow
259
+ Inherits Window
260
+
261
+ Public Sub New()
262
+ InitializeComponent()
263
+ DataContext = New MainWindowViewModel()
264
+ End Sub
265
+ End Class
266
+ ```
267
+ [NuGet Gallery | CommunityToolkit.Mvvm 8.2.1](https://www.nuget.org/packages/CommunityToolkit.Mvvm/8.2.1)
268
+ [NuGet Gallery | MaterialDesignThemes 4.9.0](https://www.nuget.org/packages/MaterialDesignThemes/4.9.0)
269
+
270
+ ![アプリ動画](https://ddjkaamml8q8x.cloudfront.net/questions/2023-08-29/28bd3bc5-220c-4428-ace9-e1443feac0d2.gif)