回答編集履歴

1

見直しキャンペーン中

2023/07/29 07:36

投稿

TN8001
TN8001

スコア9326

test CHANGED
@@ -1,427 +1,215 @@
1
1
  ---
2
2
 
3
-
4
-
5
3
  > UniformGridについては検討してみようと思います.
6
4
 
7
-
8
-
9
5
  `UniformGrid`の使い方例として、作ってみたものをあげておきます。
10
6
 
11
-
12
-
13
- ```xaml
7
+ ```xml
14
-
15
8
  <Window
16
-
17
9
  x:Class="Questions365868.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
  Title="スケジュール表"
24
-
25
13
  Width="800"
26
-
27
14
  Height="450"
28
-
29
15
  MinWidth="500"
30
-
31
16
  MinHeight="225">
32
-
33
17
  <DockPanel Margin="10">
34
18
 
35
-
36
-
37
19
  <Grid DockPanel.Dock="Top">
38
-
39
20
  <StackPanel Orientation="Horizontal">
40
-
41
21
  <Label Content="選択した年月: " />
42
-
43
22
  <ComboBox
44
-
45
23
  x:Name="selectedYear"
46
-
47
24
  ItemStringFormat="{}{0}年"
48
-
49
25
  SelectionChanged="SelectionChanged" />
50
-
51
26
  <!-- どちらを変えてもやること(セルの入れ替え)は同じなので同一ハンドラで -->
52
-
53
27
  <ComboBox
54
-
55
28
  x:Name="selectedMonth"
56
-
57
29
  ItemStringFormat="{}{0}月"
58
-
59
30
  SelectionChanged="SelectionChanged" />
60
-
61
31
  </StackPanel>
62
-
63
32
  <Label
64
-
65
33
  x:Name="today"
66
-
67
34
  HorizontalAlignment="Center"
68
-
69
35
  Content="今日の日付: " />
70
-
71
36
  </Grid>
72
37
 
73
-
74
-
75
38
  <GroupBox x:Name="calendarGroup" Header="yyyy年MM月">
76
-
77
39
  <Border BorderBrush="Black" BorderThickness="1">
78
-
79
40
  <DockPanel>
80
-
81
41
  <UniformGrid Columns="7" DockPanel.Dock="Top">
82
-
83
42
  <UniformGrid.Resources>
84
-
85
43
  <!-- UniformGridの子孫のLabelに自動適用 -->
86
-
87
44
  <Style TargetType="Label">
88
-
89
45
  <Setter Property="Background" Value="#ff8000" />
90
-
91
46
  <Setter Property="FontSize" Value="11" />
92
-
93
47
  <Setter Property="HorizontalContentAlignment" Value="Center" />
94
-
95
48
  <Setter Property="Margin" Value="1,0,0,0" />
96
-
97
49
  <Setter Property="Padding" Value="0" />
98
-
99
50
  </Style>
100
-
101
51
  </UniformGrid.Resources>
102
-
103
52
  <Label Margin="0" Content="日" />
104
-
105
53
  <Label Content="月" />
106
-
107
54
  <Label Content="火" />
108
-
109
55
  <Label Content="水" />
110
-
111
56
  <Label Content="木" />
112
-
113
57
  <Label Content="金" />
114
-
115
58
  <Label Content="土" />
116
-
117
59
  </UniformGrid>
118
60
 
119
-
120
-
121
61
  <UniformGrid
122
-
123
62
  x:Name="calenderGrid"
124
-
125
63
  Background="#d3d3d3"
126
-
127
64
  Columns="7"
128
-
129
65
  PreviewMouseLeftButtonDown="LeftButtonDown" />
130
-
131
66
  <!-- 各セルにイベントをつけるのは面倒なのでUniformGridでまとめてハンドル -->
132
-
133
67
  </DockPanel>
134
-
135
68
  </Border>
136
-
137
69
  </GroupBox>
138
-
139
70
  </DockPanel>
140
-
141
71
  </Window>
142
-
143
72
  ```
144
73
 
145
-
146
-
147
- ```C#
74
+ ```cs
148
-
149
75
  using System;
150
-
151
76
  using System.Collections.Generic;
152
-
153
77
  using System.Linq;
154
-
155
78
  using System.Windows;
156
-
157
79
  using System.Windows.Controls;
158
-
159
80
  using System.Windows.Input;
160
-
161
81
  using System.Windows.Media;
162
-
163
82
  using System.Windows.Shapes;
164
83
 
165
-
166
-
167
84
  namespace Questions365868
168
-
169
85
  {
170
-
171
86
  public partial class MainWindow : Window
172
-
173
87
  {
174
-
175
88
  private readonly Dictionary<DateTime, string> memos = new Dictionary<DateTime, string>
176
-
177
- {
89
+ {
178
-
179
- { new DateTime(2021, 10, 8), "Windows11 Release????????" },
90
+ { new DateTime(2021, 10, 8), "Windows11 Release🐱💻" },
180
-
181
- { new DateTime(2021, 11, 9), ".NET 6 launch!????" },
91
+ { new DateTime(2021, 11, 9), ".NET 6 launch!🎉" },
182
-
183
92
  { DateTime.Now.Date, "test" },
184
-
185
93
  };
186
94
 
187
-
188
-
189
95
  private Rectangle currentRect; // 選択中(枠の表示中)のRectangle
190
-
191
96
  private TextBox currentTextBox; // 編集中のTextBox
192
97
 
193
-
194
-
195
98
  public MainWindow()
196
-
197
- {
99
+ {
198
-
199
100
  InitializeComponent();
200
101
 
201
-
202
-
203
102
  var d = DateTime.Now.Date;
204
-
205
103
  today.Content = $"今日の日付: {d:yyyy年MM月dd日}";
206
104
 
207
-
208
-
209
105
  selectedYear.ItemsSource = Enumerable.Range(1999, 102); // 1999~2100
210
-
211
106
  selectedYear.SelectedItem = d.Year;
212
107
 
213
-
214
-
215
108
  selectedMonth.ItemsSource = Enumerable.Range(1, 12);
216
-
217
109
  selectedMonth.SelectedItem = d.Month;
218
-
219
- }
110
+ }
220
-
221
-
222
111
 
223
112
  private void SelectionChanged(object sender, SelectionChangedEventArgs e)
224
-
225
- {
113
+ {
226
-
227
114
  if (selectedYear.SelectedItem == null || selectedMonth.SelectedItem == null) return;
228
115
 
229
-
230
-
231
116
  calenderGrid.Children.Clear();
232
117
 
233
-
234
-
235
118
  var year = (int)selectedYear.SelectedItem;
236
-
237
119
  var month = (int)selectedMonth.SelectedItem;
238
120
 
239
-
240
-
241
121
  var d = new DateTime(year, month, 1); // 選択年月のついたち
242
-
243
122
  calendarGroup.Header = $"{d:yyyy年MM月}";
244
-
245
123
  calenderGrid.FirstColumn = (int)d.DayOfWeek; // ついたちの位置をオフセット
246
124
 
247
-
248
-
249
125
  while (month == d.Month) // 月が替わるまでループ
250
-
251
- {
126
+ {
252
-
253
127
  AddCell(d); // UniformGridに1日分のセルを追加
254
-
255
128
  d = d.AddDays(1); // 次の日
256
-
257
129
  }
258
-
259
- }
130
+ }
260
-
261
-
262
131
 
263
132
  private void AddCell(DateTime date)
264
-
265
- {
133
+ {
266
-
267
134
  var grid = new Grid { Background = Brushes.White, }; // セルをまとめるGrid UniformGridのグレーを隠すため白
268
-
269
135
  grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(), });
270
-
271
136
  grid.RowDefinitions.Add(new RowDefinition());
272
137
 
273
-
274
-
275
138
  var textBlock = new TextBlock // 日付表示
276
-
277
- {
139
+ {
278
-
279
140
  FontSize = 10,
280
-
281
141
  Foreground = date.DayOfWeek == DayOfWeek.Sunday ? Brushes.Red
282
-
283
142
  : date.DayOfWeek == DayOfWeek.Saturday ? Brushes.Blue
284
-
285
143
  : Brushes.Black,
286
-
287
144
  Padding = new Thickness(5, 0, 0, 0),
288
-
289
145
  Text = $"{date.Day}",
290
-
291
146
  };
292
-
293
147
  grid.Children.Add(textBlock);
294
148
 
295
-
296
-
297
149
  var textBox = new TextBox // メモ欄
298
-
299
- {
150
+ {
300
-
301
151
  BorderThickness = new Thickness(),
302
-
303
152
  FontSize = 10,
304
-
305
153
  Padding = new Thickness(5, 0, 0, 0),
306
-
307
154
  Text = memos.ContainsKey(date) ? memos[date] : "", // メモがあったら設定
308
-
309
155
  TextWrapping = TextWrapping.Wrap,
310
-
311
156
  };
312
-
313
157
  textBox.TextChanged += (s, e) => memos[date] = textBox.Text; // TextBoxに変更があれば都度メモも変更
314
-
315
158
  Grid.SetRow(textBox, 1);
316
-
317
159
  grid.Children.Add(textBox);
318
160
 
319
-
320
-
321
161
  var rectangle = new Rectangle // 枠
322
-
323
- {
162
+ {
324
-
325
163
  Fill = Brushes.Transparent,
326
-
327
164
  Stroke = Brushes.Black,
328
-
329
165
  StrokeDashArray = new DoubleCollection { 1, },
330
-
331
166
  StrokeThickness = 0,
332
-
333
167
  Tag = textBox, // TextBoxをTagに保存(セコいがLeftButtonDownで欲しいので^^;
334
-
335
168
  };
336
-
337
169
  Grid.SetRowSpan(rectangle, 2);
338
-
339
170
  grid.Children.Add(rectangle);
340
171
 
341
-
342
-
343
172
  calenderGrid.Children.Add(grid);
344
-
345
- }
173
+ }
346
-
347
-
348
174
 
349
175
  private void LeftButtonDown(object sender, MouseButtonEventArgs e)
350
-
351
- {
176
+ {
352
-
353
177
  if (e.Source is Rectangle rectangle) // Transparentならばここにくる nullだとこない(つまりTextBoxの編集の邪魔にならないということ)
354
-
355
- {
178
+ {
356
-
357
179
  var textBox = rectangle.Tag as TextBox; // Tagに保存したTextBoxを取得
358
-
359
180
  if (e.ClickCount == 1) // クリック
360
-
361
181
  {
362
-
363
182
  if (currentRect != null && currentRect != rectangle) // ほかのセルに枠表示があれば...表示を消す
364
-
365
183
  {
366
-
367
184
  currentRect.StrokeThickness = 0; // 枠の非表示
368
-
369
185
  currentRect.Fill = Brushes.Transparent; // 編集中ならnullになっているので戻す
370
-
371
186
  }
372
-
373
187
  currentRect = rectangle; // カレントに設定
374
-
375
188
  currentRect.StrokeThickness = 1; // 枠の表示
376
189
 
377
-
378
-
379
190
  if (currentTextBox != null && currentTextBox != textBox) // ほかのセルを編集中なら...編集終了
380
-
381
191
  {
382
-
383
192
  currentTextBox.Select(0, 0); // 文字選択解除
384
-
385
193
  currentTextBox = null; // カレントをクリア
386
-
387
194
  Keyboard.ClearFocus(); // キャレットが残るのでフォーカスを外す
388
-
389
195
  }
390
-
391
196
  }
392
197
 
393
-
394
-
395
198
  if (e.ClickCount == 2) // ダブルクリック
396
-
397
199
  {
398
-
399
200
  if (currentTextBox != textBox) e.Handled = true; // ダブルクリックをTextBoxに通してしまうと文字が全選択されるのでブロック(そのほうが都合がよければこの行はいらない)
400
-
401
201
  currentRect.Fill = null; // nullにしてRectangleの当たり判定を消す(TextBoxの編集可)
402
-
403
202
  currentTextBox = textBox; // カレントに設定
404
-
405
203
  currentTextBox.Focus(); // すぐ編集できるようにフォーカス
406
-
407
204
  }
408
-
409
205
  }
410
-
411
- }
206
+ }
412
-
413
207
  }
414
-
415
208
  }
416
-
417
209
  ```
418
-
210
+ ![アプリ画像](https://ddjkaamml8q8x.cloudfront.net/questions/2023-07-29/af237994-8f62-4528-b87b-f7f8c4205574.png)
419
-
420
211
 
421
212
  ---
422
213
 
423
-
424
-
425
214
  余裕があれば`ItemsControl`や`Binding`などを調べてもらうと、よりWPFっぽい作りになると思います^^
426
-
427
215
  [MVVM - 【WPF】Viewへのコントロールの追加|teratail](https://teratail.com/questions/333874)