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

回答編集履歴

1

見直しキャンペーン中

2023/07/25 15:15

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,42 +1,298 @@
1
- グラフをそのように表示するんですか。。。
2
- 通常折れ線グラフの横軸(今回は縦ですが)は時系列等の推移を見るもので、この例には向いていないように思います。
3
- しかし別質問もありますし、それは置いておきます。
4
-
5
- 現状ある程度動いているのであれば、
6
- ```xaml
7
- <Canvas x:Name="DetailNm" Visibility="{Binding IsDetail}" />
8
- <Canvas x:Name="Detail" Visibility="{Binding IsDetail}" />
9
-
10
- <!-- IsDetailがboolなら
11
- <Canvas x:Name="DetailNm" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}" />
12
- <Canvas x:Name="Detail" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}"/>
13
- -->
14
- ```
15
-
16
- ```C#
17
- private void BtnDetail_Click(object sender, RoutedEventArgs e)
18
- {
19
- var button = sender as Button;
20
- var area = button?.DataContext as Area;
21
-
22
- if (area != null)
23
- {
24
- foreach (Area a in AreaList)
25
- {
26
- a.IsDetail = Visibility.Collapsed;
27
- }
28
- area.IsDetail = Visibility.Visible;
29
- }
30
- }
31
- ```
32
- のような感じで開閉はできると思います。
33
-
34
- `RadioButton`を使えばコードビハインドいらずですみますが、すべて閉じることができなくなるので一長一短ですね。
35
-
36
- ---
37
-
38
- この表示にこだわる場合は使えるかどうかちょっとわかりませんが、`DataGrid`の行の詳細やグループ化で畳むような表現はあります。
39
-
40
- [方法: DataGrid コントロールに行の詳細を追加する - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/controls/how-to-add-row-details-to-a-datagrid-control)
41
-
42
- [方法: DataGrid コントロールでデータをグループ化、並べ替え、およびフィルター処理する - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/controls/how-to-group-sort-and-filter-data-in-the-datagrid-control)
1
+ グラフをそのように表示するんですか。。。
2
+ 通常折れ線グラフの横軸(今回は縦ですが)は時系列等の推移を見るもので、この例には向いていないように思います。
3
+ しかし別質問もありますし、それは置いておきます。
4
+
5
+ 現状ある程度動いているのであれば、↓のような感じで開閉はできると思います。
6
+ ```xml
7
+ <Canvas x:Name="DetailNm" Visibility="{Binding IsDetail}" />
8
+ <Canvas x:Name="Detail" Visibility="{Binding IsDetail}" />
9
+
10
+ <!-- IsDetailがboolなら
11
+ <Canvas x:Name="DetailNm" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}" />
12
+ <Canvas x:Name="Detail" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}"/>
13
+ -->
14
+ ```
15
+
16
+ ```cs
17
+ private void BtnDetail_Click(object sender, RoutedEventArgs e)
18
+ {
19
+ if ((sender as Button)?.DataContext is Area area)
20
+ {
21
+ foreach (var a in AreaList) a.IsDetail = false;
22
+ area.IsDetail = true;
23
+ }
24
+ }
25
+ ```
26
+
27
+ `RadioButton`を使えばコードビハインドいらずですみますが、すべて閉じることができなくなるので一長一短ですね。
28
+
29
+ ---
30
+
31
+ この表示にこだわる場合は使えるかどうかちょっとわかりませんが、`DataGrid`の行の詳細やグループ化で畳むような表現はあります。
32
+
33
+ [方法: DataGrid コントロールに行の詳細を追加する - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/controls/how-to-add-row-details-to-a-datagrid-control)
34
+
35
+ [方法: DataGrid コントロールでデータをグループ化、並べ替え、およびフィルター処理する - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/controls/how-to-group-sort-and-filter-data-in-the-datagrid-control)
36
+
37
+ ---
38
+
39
+ ```xml
40
+ <Window
41
+ x:Class="Questions311409.MainWindow"
42
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
43
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
+ Width="800"
45
+ Height="450">
46
+ <Window.Resources>
47
+ <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
48
+ <Style
49
+ x:Key="ButtonStyle"
50
+ BasedOn="{StaticResource {x:Type ToggleButton}}"
51
+ TargetType="{x:Type RadioButton}" />
52
+ </Window.Resources>
53
+
54
+ <Border
55
+ Margin="5"
56
+ Background="LightGray"
57
+ BorderBrush="Black"
58
+ BorderThickness="1">
59
+ <Grid>
60
+ <Grid.RowDefinitions>
61
+ <RowDefinition Height="50" />
62
+ <RowDefinition Height="*" />
63
+ <RowDefinition Height="Auto" />
64
+ </Grid.RowDefinitions>
65
+ <Grid.ColumnDefinitions>
66
+ <ColumnDefinition Width="Auto" />
67
+ <ColumnDefinition Width="*" />
68
+ </Grid.ColumnDefinitions>
69
+
70
+ <ScrollViewer
71
+ x:Name="ColumnHeader"
72
+ Grid.Column="1"
73
+ ScrollViewer.HorizontalScrollBarVisibility="Hidden"
74
+ ScrollViewer.VerticalScrollBarVisibility="Hidden">
75
+ <Border BorderBrush="DimGray" BorderThickness="1">
76
+ <StackPanel x:Name="YokoSenPanel" Orientation="Vertical" />
77
+ </Border>
78
+ </ScrollViewer>
79
+
80
+ <ScrollViewer
81
+ x:Name="RowHeader"
82
+ Grid.Row="1"
83
+ ScrollChanged="ScrollChanged"
84
+ ScrollViewer.HorizontalScrollBarVisibility="Hidden"
85
+ ScrollViewer.VerticalScrollBarVisibility="Hidden">
86
+ <ItemsControl x:Name="Test2" ItemsSource="{Binding AreaList}">
87
+ <ItemsControl.ItemTemplate>
88
+ <DataTemplate>
89
+ <Border
90
+ Padding="5"
91
+ BorderBrush="DimGray"
92
+ BorderThickness="1">
93
+ <StackPanel>
94
+ <StackPanel Orientation="Horizontal">
95
+ <Label x:Name="AreaName" Content="{Binding TenpoMei}" />
96
+ <RadioButton
97
+ Content="詳細"
98
+ GroupName="Area"
99
+ IsChecked="{Binding IsDetail}"
100
+ Style="{StaticResource ButtonStyle}" />
101
+ </StackPanel>
102
+ <ItemsControl
103
+ Margin="20,0,0,0"
104
+ ItemsSource="{Binding Items}"
105
+ Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}">
106
+ <ItemsControl.ItemTemplate>
107
+ <DataTemplate>
108
+ <TextBlock Text="{Binding ShouhinMei}" />
109
+ </DataTemplate>
110
+ </ItemsControl.ItemTemplate>
111
+ </ItemsControl>
112
+ </StackPanel>
113
+ </Border>
114
+ </DataTemplate>
115
+ </ItemsControl.ItemTemplate>
116
+ </ItemsControl>
117
+ </ScrollViewer>
118
+
119
+ <ScrollViewer
120
+ x:Name="AreaSenViewer"
121
+ Grid.Row="1"
122
+ Grid.RowSpan="2"
123
+ Grid.Column="1"
124
+ Background="White"
125
+ ScrollChanged="ScrollChanged"
126
+ ScrollViewer.HorizontalScrollBarVisibility="Auto"
127
+ ScrollViewer.VerticalScrollBarVisibility="Visible">
128
+ <ItemsControl
129
+ x:Name="Test"
130
+ AlternationCount="2"
131
+ ItemsSource="{Binding AreaList}">
132
+ <ItemsControl.ItemTemplate>
133
+ <DataTemplate>
134
+ <Border
135
+ Padding="5"
136
+ BorderBrush="DimGray"
137
+ BorderThickness="1">
138
+ <StackPanel HorizontalAlignment="Left">
139
+ <Grid>
140
+ <!-- 高さ合わせ用ダミー -->
141
+ <Label
142
+ x:Name="dummy"
143
+ Content="{Binding TenpoMei}"
144
+ Visibility="Hidden" />
145
+ <Canvas x:Name="Area" Width="{Binding Goukei}">
146
+ <Line
147
+ x:Name="Line"
148
+ Stroke="SkyBlue"
149
+ StrokeThickness="10"
150
+ X2="{Binding Goukei}"
151
+ Y1="16"
152
+ Y2="16" />
153
+ <TextBlock Text="{Binding Jyuni}" />
154
+ </Canvas>
155
+ </Grid>
156
+
157
+ <ItemsControl ItemsSource="{Binding Items}" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}, Mode=OneWay}">
158
+ <ItemsControl.ItemTemplate>
159
+ <DataTemplate>
160
+ <Grid>
161
+ <Canvas x:Name="Detail">
162
+ <Line
163
+ HorizontalAlignment="Center"
164
+ VerticalAlignment="Center"
165
+ Stroke="YellowGreen"
166
+ StrokeThickness="10"
167
+ X2="{Binding Uriage}"
168
+ Y1="11"
169
+ Y2="11" />
170
+ </Canvas>
171
+ <TextBlock Text="{Binding Uriage}" />
172
+ </Grid>
173
+ </DataTemplate>
174
+ </ItemsControl.ItemTemplate>
175
+ </ItemsControl>
176
+ </StackPanel>
177
+ </Border>
178
+ </DataTemplate>
179
+ </ItemsControl.ItemTemplate>
180
+ </ItemsControl>
181
+ </ScrollViewer>
182
+
183
+ <!--
184
+ 水平スクロールバー表示非表示時の位置合わせ用ダミー
185
+ 微妙に表示タイミングがずれるが、ちゃんとやろうとするとかなり面倒
186
+ -->
187
+ <ScrollBar
188
+ Grid.Row="2"
189
+ Width="0"
190
+ Orientation="Horizontal"
191
+ Visibility="{Binding ComputedHorizontalScrollBarVisibility, ElementName=AreaSenViewer, Mode=OneWay}" />
192
+ </Grid>
193
+ </Border>
194
+ </Window>
195
+ ```
196
+
197
+ ```cs
198
+ using System.Collections.Generic;
199
+ using System.Collections.ObjectModel;
200
+ using System.ComponentModel;
201
+ using System.Linq;
202
+ using System.Runtime.CompilerServices;
203
+ using System.Windows;
204
+ using System.Windows.Controls;
205
+
206
+ namespace Questions311409
207
+ {
208
+ public class Observable : INotifyPropertyChanged
209
+ {
210
+ public event PropertyChangedEventHandler PropertyChanged;
211
+ protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
212
+ {
213
+ if (Equals(storage, value)) return;
214
+ storage = value;
215
+ OnPropertyChanged(propertyName);
216
+ }
217
+ protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
218
+ }
219
+
220
+ public class Area : Observable
221
+ {
222
+ public string TenpoMei { get; }
223
+
224
+ public bool IsDetail { get => _IsDetail; set => Set(ref _IsDetail, value); }
225
+ private bool _IsDetail;
226
+
227
+ public string Jyuni { get; }
228
+
229
+ public int Goukei => Items.Sum(x => x.Uriage);
230
+
231
+ public List<Item> Items { get; } = new List<Item>();
232
+
233
+
234
+ public Area(string tenpoMei, string jyuni, params Item[] items)
235
+ {
236
+ TenpoMei = tenpoMei;
237
+ Jyuni = jyuni;
238
+
239
+ foreach (var item in items) Items.Add(item);
240
+ }
241
+ }
242
+
243
+ public class Item
244
+ {
245
+ public string ShouhinMei { get; }
246
+
247
+ public int Uriage { get; }
248
+
249
+ public Item(string shouhinMei, int uriage)
250
+ {
251
+ ShouhinMei = shouhinMei;
252
+ Uriage = uriage;
253
+ }
254
+ }
255
+
256
+ public partial class MainWindow : Window
257
+ {
258
+ public ObservableCollection<Area> AreaList { get; }
259
+
260
+ public MainWindow()
261
+ {
262
+ InitializeComponent();
263
+
264
+ AreaList = new ObservableCollection<Area>
265
+ {
266
+ new Area("A店","2位", new Item("商品1", 30), new Item("商品2", 100), new Item("商品3", 70)),
267
+ new Area("B店","1位", new Item("商品1", 50), new Item("商品2", 150), new Item("商品3", 100)),
268
+ new Area("C店","3位", new Item("商品1", 10), new Item("商品2", 60), new Item("商品4", 30)),
269
+ };
270
+
271
+ DataContext = this;
272
+ }
273
+
274
+ private void ScrollChanged(object sender, ScrollChangedEventArgs e)
275
+ {
276
+ if (sender == RowHeader)
277
+ {
278
+ AreaSenViewer.ScrollToVerticalOffset(e.VerticalOffset);
279
+ }
280
+ if (sender == AreaSenViewer)
281
+ {
282
+ RowHeader.ScrollToVerticalOffset(e.VerticalOffset);
283
+ }
284
+ }
285
+
286
+ private void BtnDetail_Click(object sender, RoutedEventArgs e)
287
+ {
288
+ if ((sender as Button)?.DataContext is Area area)
289
+ {
290
+ foreach (var a in AreaList) a.IsDetail = false;
291
+
292
+ area.IsDetail = true;
293
+ }
294
+ }
295
+ }
296
+ }
297
+ ```
298
+ ![アプリ画像](https://ddjkaamml8q8x.cloudfront.net/questions/2023-07-26/04473acd-4d11-4786-9f4f-f758695990bf.png)