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

回答編集履歴

4

見直しキャンペーン中

2023/07/25 13:57

投稿

TN8001
TN8001

スコア10112

answer CHANGED
@@ -1,217 +1,217 @@
1
- > ボタンクリックで動的に作成したタブの中に、別に作成した子画面の内容を表示させたい。
2
-
3
- 方法はいろいろあります。私ならこうするかな?という案です。
4
- それぞれ独立性の高い子画面なら、`DataTemplate`でビューを切り替えるのがいいと思います。
5
-
6
-
7
- > TabControlの表示/非表示を切り替えたい
8
-
9
- まあどちらでもいいんですが、`Image`の`Visibility`を`bool`で切り替えてみました。
10
-
11
-
12
- ```xaml
13
- <Window
14
- x:Class="Questions309980.MainWindow"
15
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
16
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
17
- xmlns:local="clr-namespace:Questions309980"
18
- Title="MainWindow"
19
- Width="800"
20
- Height="450">
21
- <Window.DataContext>
22
- <local:MainViewModel />
23
- </Window.DataContext>
24
- <Window.Resources>
25
- <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
26
- <Style TargetType="{x:Type Button}">
27
- <Setter Property="Margin" Value="5" />
28
- <Setter Property="MinWidth" Value="80" />
29
- </Style>
30
-
31
- <!-- DataTemplateでタブのコンテントを切り替える -->
32
- <!-- UserControlを作ってもいいし -->
33
- <DataTemplate DataType="{x:Type local:ToDoViewModel}">
34
- <local:ToDoView />
35
- </DataTemplate>
36
-
37
- <!-- 簡単な内容ならこの場で作ってもいい -->
38
- <DataTemplate DataType="{x:Type local:CalendarViewModel}">
39
- <DockPanel>
40
- <TextBlock
41
- DockPanel.Dock="Top"
42
- FontSize="24"
43
- FontWeight="Bold"
44
- Text="Calendar" />
45
- <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
46
- <Button Command="{Binding HogeCommand}" Content="Hoge" />
47
- </StackPanel>
48
- <Calendar HorizontalAlignment="Left" VerticalAlignment="Top" SelectedDate="{Binding SelectedDate}" />
49
- </DockPanel>
50
- </DataTemplate>
51
- </Window.Resources>
52
-
53
- <DockPanel>
54
- <TextBlock Text="{Binding StatusMessage}" HorizontalAlignment="Right" DockPanel.Dock="Bottom" />
55
-
56
- <GroupBox Background="Papayawhip">
57
- <StackPanel>
58
- <Button Command="{Binding Command}" CommandParameter="{x:Type local:ToDoViewModel}" Content="ToDo" />
59
- <Button Command="{Binding Command}" CommandParameter="{x:Type local:CalendarViewModel}" Content="Calendar" />
60
- </StackPanel>
61
- </GroupBox>
62
-
63
- <Grid>
64
- <TabControl ItemsSource="{Binding TabItems}" SelectedItem="{Binding SelectedItem}">
65
- <TabControl.ItemTemplate>
66
- <DataTemplate>
67
- <TextBlock Text="{Binding TabHeader}" />
68
- </DataTemplate>
69
- </TabControl.ItemTemplate>
70
- </TabControl>
71
-
72
- <!-- はじめは上に重なってTabControlを隠している -->
73
- <Image
74
- HorizontalAlignment="Left"
75
- VerticalAlignment="Top"
76
- Source="https://teratail-v2.storage.googleapis.com/uploads/avatars/u13/132786/KnkDDC5A_thumbnail.jpg"
77
- Visibility="{Binding IsImageVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
78
- </Grid>
79
- </DockPanel>
80
- </Window>
81
- ```
82
-
83
- ```xaml
84
- <UserControl
85
- x:Class="Questions309980.ToDoView"
86
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
87
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
88
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
89
- xmlns:local="clr-namespace:Questions309980"
90
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
91
- d:DesignHeight="450"
92
- d:DesignWidth="800"
93
- mc:Ignorable="d">
94
- <DockPanel>
95
- <TextBlock
96
- DockPanel.Dock="Top"
97
- FontSize="24"
98
- FontWeight="Bold"
99
- Text="ToDo" />
100
- <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
101
- <Button Command="{Binding AddCommand}" Content="Add" />
102
- <Button Command="{Binding DelCommand}" Content="Del" />
103
- <Button Command="{Binding DoneCommand}" Content="Done" />
104
- </StackPanel>
105
- <ListBox>
106
- <ListBoxItem Content="aaa" />
107
- <ListBoxItem Content="bbb" />
108
- <ListBoxItem Content="ccc" />
109
- </ListBox>
110
- </DockPanel>
111
- </UserControl>
112
- ```
113
-
114
- ```C#
115
- using Prism.Commands;
116
- using Prism.Mvvm;
117
- using System;
118
- using System.Collections.ObjectModel;
119
- using System.Diagnostics;
120
- using System.Linq;
121
-
122
- namespace Questions309980
123
- {
124
- public class MainViewModel : BindableBase
125
- {
126
- private bool _IsImageVisible = true;
127
- public bool IsImageVisible { get => _IsImageVisible; set => SetProperty(ref _IsImageVisible, value); }
128
-
129
- private TabItemBase _SelectedItem;
130
- public TabItemBase SelectedItem { get => _SelectedItem; set => SetProperty(ref _SelectedItem, value); }
131
-
132
- private string _StatusMessage;
133
- public string StatusMessage { get => _StatusMessage; set => SetProperty(ref _StatusMessage, value); }
134
-
135
- public ObservableCollection<TabItemBase> TabItems { get; } = new();
136
-
137
- public DelegateCommand<Type> Command { get; }
138
-
139
-
140
- public MainViewModel()
141
- {
142
- Command = new(type =>
143
- {
144
- // ImageのVisibilityを切り替える
145
- IsImageVisible = false;
146
-
147
- // switch文等で作り分けてもいいが、面倒なので型(Type)から直で生成
148
- var item = (TabItemBase)Activator.CreateInstance(type);
149
-
150
- // item追加
151
- TabItems.Add(item);
152
-
153
- // item選択
154
- SelectedItem = item;
155
-
156
- // CanExecuteを再確認させる
157
- Command.RaiseCanExecuteChanged();
158
-
159
- StatusMessage = $"{type.Name} 読み込み";
160
- },
161
- // 同じボタンは2回押せないようにする(TabItemsにすでに同じ型があるかどうか)
162
- type => !TabItems.Any(x => x.GetType().Equals(type)));
163
- }
164
- }
165
-
166
- public abstract class TabItemBase : BindableBase
167
- {
168
- public string TabHeader { get; }
169
- public TabItemBase(string header) => TabHeader = header;
170
- }
171
-
172
- public class ToDoViewModel : TabItemBase
173
- {
174
- public DelegateCommand AddCommand { get; }
175
- public DelegateCommand DelCommand { get; }
176
- public DelegateCommand DoneCommand { get; }
177
-
178
-
179
- public ToDoViewModel() : base("ToDo")
180
- {
181
- AddCommand = new(() => Debug.WriteLine("AddCommand"));
182
- DelCommand = new(() => Debug.WriteLine("DelCommand"));
183
- DoneCommand = new(() => Debug.WriteLine("DoneCommand"));
184
- }
185
- }
186
-
187
- public class CalendarViewModel : TabItemBase
188
- {
189
- private DateTime _SelectedDate;
190
- public DateTime SelectedDate { get => _SelectedDate; set => SetProperty(ref _SelectedDate, value); }
191
-
192
- public DelegateCommand HogeCommand { get; }
193
-
194
-
195
- public CalendarViewModel() : base("Calendar") => HogeCommand = new(() => Debug.WriteLine(SelectedDate));
196
- }
197
- }
198
- ```
199
-
200
- `BindableBase`・`DelegateCommand`は、`Prism.Core`を使用しました。
201
- [NuGet Gallery | Prism.Core 8.0.0.1909](https://www.nuget.org/packages/Prism.Core/)
202
-
203
- 特に指定がないので`.NET 5.0`で書きました^^
204
- `.NET Framework 4.8`等では、`new()`でエラーが出るので型を書いてください。
205
-
206
- [Target-typed new expressions - C# 9.0 specification proposals | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/proposals/csharp-9.0/target-typed-new)
207
- [ターゲットからの new 型推論 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/oo_construct.html#target-typed-new)
208
- ![アプリ画像](a4b60c0e0e865cbbc60deab1a895b098.png)
209
-
210
- ---
211
-
212
- [[Q&A] WPF MVVMの学習 - Qiita](https://qiita.com/choni-k/questions/8973d506bcca4722ce2c)
213
-
214
- > teratailでは、マルチポスト※の推奨はしていません。
215
-
216
- [ヘルプ|teratail(テラテイル)](https://teratail.com/help#posted-otherservice)
1
+ > ボタンクリックで動的に作成したタブの中に、別に作成した子画面の内容を表示させたい。
2
+
3
+ 方法はいろいろあります。私ならこうするかな?という案です。
4
+ それぞれ独立性の高い子画面なら、`DataTemplate`でビューを切り替えるのがいいと思います。
5
+
6
+
7
+ > TabControlの表示/非表示を切り替えたい
8
+
9
+ まあどちらでもいいんですが、`Image`の`Visibility`を`bool`で切り替えてみました。
10
+
11
+
12
+ ```xml
13
+ <Window
14
+ x:Class="Questions309980.MainWindow"
15
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
16
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
17
+ xmlns:local="clr-namespace:Questions309980"
18
+ Title="MainWindow"
19
+ Width="800"
20
+ Height="450">
21
+ <Window.DataContext>
22
+ <local:MainViewModel />
23
+ </Window.DataContext>
24
+ <Window.Resources>
25
+ <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
26
+ <Style TargetType="{x:Type Button}">
27
+ <Setter Property="Margin" Value="5" />
28
+ <Setter Property="MinWidth" Value="80" />
29
+ </Style>
30
+
31
+ <!-- DataTemplateでタブのコンテントを切り替える -->
32
+ <!-- UserControlを作ってもいいし -->
33
+ <DataTemplate DataType="{x:Type local:ToDoViewModel}">
34
+ <local:ToDoView />
35
+ </DataTemplate>
36
+
37
+ <!-- 簡単な内容ならこの場で作ってもいい -->
38
+ <DataTemplate DataType="{x:Type local:CalendarViewModel}">
39
+ <DockPanel>
40
+ <TextBlock
41
+ DockPanel.Dock="Top"
42
+ FontSize="24"
43
+ FontWeight="Bold"
44
+ Text="Calendar" />
45
+ <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
46
+ <Button Command="{Binding HogeCommand}" Content="Hoge" />
47
+ </StackPanel>
48
+ <Calendar HorizontalAlignment="Left" VerticalAlignment="Top" SelectedDate="{Binding SelectedDate}" />
49
+ </DockPanel>
50
+ </DataTemplate>
51
+ </Window.Resources>
52
+
53
+ <DockPanel>
54
+ <TextBlock Text="{Binding StatusMessage}" HorizontalAlignment="Right" DockPanel.Dock="Bottom" />
55
+
56
+ <GroupBox Background="Papayawhip">
57
+ <StackPanel>
58
+ <Button Command="{Binding Command}" CommandParameter="{x:Type local:ToDoViewModel}" Content="ToDo" />
59
+ <Button Command="{Binding Command}" CommandParameter="{x:Type local:CalendarViewModel}" Content="Calendar" />
60
+ </StackPanel>
61
+ </GroupBox>
62
+
63
+ <Grid>
64
+ <TabControl ItemsSource="{Binding TabItems}" SelectedItem="{Binding SelectedItem}">
65
+ <TabControl.ItemTemplate>
66
+ <DataTemplate>
67
+ <TextBlock Text="{Binding TabHeader}" />
68
+ </DataTemplate>
69
+ </TabControl.ItemTemplate>
70
+ </TabControl>
71
+
72
+ <!-- はじめは上に重なってTabControlを隠している -->
73
+ <Image
74
+ HorizontalAlignment="Left"
75
+ VerticalAlignment="Top"
76
+ Source="https://teratail-v2.storage.googleapis.com/uploads/avatars/u13/132786/KnkDDC5A_thumbnail.jpg"
77
+ Visibility="{Binding IsImageVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
78
+ </Grid>
79
+ </DockPanel>
80
+ </Window>
81
+ ```
82
+
83
+ ```xml
84
+ <UserControl
85
+ x:Class="Questions309980.ToDoView"
86
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
87
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
88
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
89
+ xmlns:local="clr-namespace:Questions309980"
90
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
91
+ d:DesignHeight="450"
92
+ d:DesignWidth="800"
93
+ mc:Ignorable="d">
94
+ <DockPanel>
95
+ <TextBlock
96
+ DockPanel.Dock="Top"
97
+ FontSize="24"
98
+ FontWeight="Bold"
99
+ Text="ToDo" />
100
+ <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
101
+ <Button Command="{Binding AddCommand}" Content="Add" />
102
+ <Button Command="{Binding DelCommand}" Content="Del" />
103
+ <Button Command="{Binding DoneCommand}" Content="Done" />
104
+ </StackPanel>
105
+ <ListBox>
106
+ <ListBoxItem Content="aaa" />
107
+ <ListBoxItem Content="bbb" />
108
+ <ListBoxItem Content="ccc" />
109
+ </ListBox>
110
+ </DockPanel>
111
+ </UserControl>
112
+ ```
113
+
114
+ ```cs
115
+ using Prism.Commands;
116
+ using Prism.Mvvm;
117
+ using System;
118
+ using System.Collections.ObjectModel;
119
+ using System.Diagnostics;
120
+ using System.Linq;
121
+
122
+ namespace Questions309980
123
+ {
124
+ public class MainViewModel : BindableBase
125
+ {
126
+ private bool _IsImageVisible = true;
127
+ public bool IsImageVisible { get => _IsImageVisible; set => SetProperty(ref _IsImageVisible, value); }
128
+
129
+ private TabItemBase _SelectedItem;
130
+ public TabItemBase SelectedItem { get => _SelectedItem; set => SetProperty(ref _SelectedItem, value); }
131
+
132
+ private string _StatusMessage;
133
+ public string StatusMessage { get => _StatusMessage; set => SetProperty(ref _StatusMessage, value); }
134
+
135
+ public ObservableCollection<TabItemBase> TabItems { get; } = new();
136
+
137
+ public DelegateCommand<Type> Command { get; }
138
+
139
+
140
+ public MainViewModel()
141
+ {
142
+ Command = new(type =>
143
+ {
144
+ // ImageのVisibilityを切り替える
145
+ IsImageVisible = false;
146
+
147
+ // switch文等で作り分けてもいいが、面倒なので型(Type)から直で生成
148
+ var item = (TabItemBase)Activator.CreateInstance(type);
149
+
150
+ // item追加
151
+ TabItems.Add(item);
152
+
153
+ // item選択
154
+ SelectedItem = item;
155
+
156
+ // CanExecuteを再確認させる
157
+ Command.RaiseCanExecuteChanged();
158
+
159
+ StatusMessage = $"{type.Name} 読み込み";
160
+ },
161
+ // 同じボタンは2回押せないようにする(TabItemsにすでに同じ型があるかどうか)
162
+ type => !TabItems.Any(x => x.GetType().Equals(type)));
163
+ }
164
+ }
165
+
166
+ public abstract class TabItemBase : BindableBase
167
+ {
168
+ public string TabHeader { get; }
169
+ public TabItemBase(string header) => TabHeader = header;
170
+ }
171
+
172
+ public class ToDoViewModel : TabItemBase
173
+ {
174
+ public DelegateCommand AddCommand { get; }
175
+ public DelegateCommand DelCommand { get; }
176
+ public DelegateCommand DoneCommand { get; }
177
+
178
+
179
+ public ToDoViewModel() : base("ToDo")
180
+ {
181
+ AddCommand = new(() => Debug.WriteLine("AddCommand"));
182
+ DelCommand = new(() => Debug.WriteLine("DelCommand"));
183
+ DoneCommand = new(() => Debug.WriteLine("DoneCommand"));
184
+ }
185
+ }
186
+
187
+ public class CalendarViewModel : TabItemBase
188
+ {
189
+ private DateTime _SelectedDate;
190
+ public DateTime SelectedDate { get => _SelectedDate; set => SetProperty(ref _SelectedDate, value); }
191
+
192
+ public DelegateCommand HogeCommand { get; }
193
+
194
+
195
+ public CalendarViewModel() : base("Calendar") => HogeCommand = new(() => Debug.WriteLine(SelectedDate));
196
+ }
197
+ }
198
+ ```
199
+
200
+ `BindableBase`・`DelegateCommand`は、`Prism.Core`を使用しました。
201
+ [NuGet Gallery | Prism.Core 8.0.0.1909](https://www.nuget.org/packages/Prism.Core/)
202
+
203
+ 特に指定がないので.NET 5.0で書きました^^
204
+ .NET Framework 4.8等では、`new()`でエラーが出るので型を書いてください。
205
+
206
+ [Target-typed new expressions - C# 9.0 specification proposals | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/proposals/csharp-9.0/target-typed-new)
207
+ [ターゲットからの new 型推論 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/oo_construct.html#target-typed-new)
208
+ ![アプリ画像](a4b60c0e0e865cbbc60deab1a895b098.png)
209
+
210
+ ---
211
+
212
+ [[Q&A] WPF MVVMの学習 - Qiita](https://qiita.com/choni-k/questions/8973d506bcca4722ce2c)
213
+
214
+ > teratailでは、マルチポスト※の推奨はしていません。
215
+
216
+ [ヘルプ|teratail(テラテイル)](https://teratail.com/help#posted-otherservice)
217
217
  上記確認の上、適切に対応してください。

3

もー

2020/12/13 21:53

投稿

TN8001
TN8001

スコア10112

answer CHANGED
@@ -139,7 +139,7 @@
139
139
 
140
140
  public MainViewModel()
141
141
  {
142
- Command = new DelegateCommand<Type>(type =>
142
+ Command = new(type =>
143
143
  {
144
144
  // ImageのVisibilityを切り替える
145
145
  IsImageVisible = false;

2

HogeCommand

2020/12/13 21:53

投稿

TN8001
TN8001

スコア10112

answer CHANGED
@@ -189,10 +189,10 @@
189
189
  private DateTime _SelectedDate;
190
190
  public DateTime SelectedDate { get => _SelectedDate; set => SetProperty(ref _SelectedDate, value); }
191
191
 
192
- public DelegateCommand Hoge { get; }
192
+ public DelegateCommand HogeCommand { get; }
193
193
 
194
194
 
195
- public CalendarViewModel() : base("Calendar") => Hoge = new(() => Debug.WriteLine(SelectedDate));
195
+ public CalendarViewModel() : base("Calendar") => HogeCommand = new(() => Debug.WriteLine(SelectedDate));
196
196
  }
197
197
  }
198
198
  ```

1

C#

2020/12/13 21:41

投稿

TN8001
TN8001

スコア10112

answer CHANGED
@@ -111,7 +111,7 @@
111
111
  </UserControl>
112
112
  ```
113
113
 
114
- ```cs
114
+ ```C#
115
115
  using Prism.Commands;
116
116
  using Prism.Mvvm;
117
117
  using System;