回答編集履歴

1

見直しキャンペーン中

2023/07/28 16:25

投稿

TN8001
TN8001

スコア9898

test CHANGED
@@ -1,457 +1,229 @@
1
1
  参考URLが誤記とはどういうことでしょうか?
2
2
 
3
-
4
-
5
3
  それに(あえてurlはだしませんが)こういった怪しげな翻訳サイト(最近日本語のも多く見ますね)ではなく元ネタを探しましょう(ほぼ Stack Overflow が元ネタ)
6
-
7
4
  [c# - How to display a dynamic object in property grid? - Stack Overflow](https://stackoverflow.com/questions/3491556/how-to-display-a-dynamic-object-in-property-grid)
8
5
 
9
-
10
-
11
6
  その回答の中で、
12
-
13
7
  > a custom TypeConverter, or (alternatively) ICustomTypeDescriptor/TypeDescriptionProvider.
14
8
 
15
-
16
-
17
9
  とありましたので [ICustomTypeDescriptor](https://docs.microsoft.com/ja-jp/dotnet/api/system.componentmodel.icustomtypedescriptor) のほうでやってみたところ動いている気がします(あっているかは自信ないです^^;
18
10
 
19
-
20
-
21
11
  参考
22
-
23
12
  [c# - Dynamic PropertyGrid properties - Stack Overflow](https://stackoverflow.com/questions/10688656/dynamic-propertygrid-properties)
24
-
25
13
  [Customized Display of Collection Data in a PropertyGrid - CodeProject](https://www.codeproject.com/Articles/4448/Customized-display-of-collection-data-in-a-Propert)
26
14
 
27
-
28
-
29
15
  `TypeConverter`でも`ConvertFrom`とかがあればいいのかもしれませんが、`PropertyGrid`を使ったことがないのでぶっちゃけ何もわかってません^^;
30
16
 
31
-
32
-
33
- ```xaml
17
+ ```xml
34
-
35
18
  <Window
36
-
37
19
  x:Class="Questions353706.MainWindow"
38
-
39
20
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
40
-
41
21
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
42
-
43
22
  xmlns:local="clr-namespace:Questions353706"
44
-
45
23
  xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
46
-
47
24
  Width="800"
48
-
49
25
  Height="450">
50
-
51
26
  <Window.DataContext>
52
-
53
27
  <local:MainWindowViewModel />
54
-
55
28
  </Window.DataContext>
56
-
57
29
  <Grid>
58
-
59
30
  <Grid.ColumnDefinitions>
60
-
61
31
  <ColumnDefinition Width="200" MinWidth="100" />
62
-
63
32
  <ColumnDefinition Width="5" />
64
-
65
33
  <ColumnDefinition Width="*" />
66
-
67
34
  </Grid.ColumnDefinitions>
68
35
 
69
-
70
-
71
36
  <DockPanel>
72
-
73
37
  <ListBox
74
-
75
38
  DisplayMemberPath="Name"
76
-
77
39
  ItemsSource="{Binding CommandList}"
78
-
79
40
  SelectedItem="{Binding CommandProperty.Value}" />
80
-
81
41
  </DockPanel>
82
42
 
83
-
84
-
85
43
  <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
86
44
 
87
-
88
-
89
45
  <DockPanel Grid.Column="2">
90
-
91
46
  <Button
92
-
93
47
  Command="{Binding TestCommand}"
94
-
95
48
  Content="Test"
96
-
97
49
  DockPanel.Dock="Bottom" />
98
-
99
50
  <xctk:PropertyGrid
100
-
101
51
  SelectedObject="{Binding CommandProperty.Value, UpdateSourceTrigger=PropertyChanged}"
102
-
103
52
  ShowSearchBox="False"
104
-
105
53
  ShowSortOptions="False" />
106
-
107
54
  </DockPanel>
108
-
109
55
  </Grid>
110
-
111
56
  </Window>
112
-
113
57
  ```
114
58
 
115
-
116
-
117
- ```C#
59
+ ```cs
118
-
119
60
  using Reactive.Bindings;
120
-
121
61
  using System;
122
-
123
62
  using System.Collections.Generic;
124
-
125
63
  using System.Collections.ObjectModel;
126
-
127
64
  using System.ComponentModel;
128
-
129
65
  using System.Diagnostics;
130
-
131
66
  using System.Linq;
132
-
133
67
  using System.Reactive.Linq;
134
-
135
68
  using System.Windows;
136
69
 
137
-
138
-
139
70
  namespace Questions353706
140
-
141
71
  {
142
-
143
72
  public class CustomObjectType : ICustomTypeDescriptor
144
-
145
- {
73
+ {
146
-
147
74
  public string Name { get; set; }
148
-
149
75
  public List<CustomProperty> Properties { get; } = new List<CustomProperty>();
150
76
 
151
-
152
-
153
77
  public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(this, true);
154
-
155
78
  public string GetClassName() => TypeDescriptor.GetClassName(this, true);
156
-
157
79
  public string GetComponentName() => TypeDescriptor.GetComponentName(this, true);
158
-
159
80
  public TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true);
160
-
161
81
  public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true);
162
-
163
82
  public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true);
164
-
165
83
  public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType, true);
166
-
167
84
  public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true);
168
-
169
85
  public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes, true);
170
-
171
86
  public PropertyDescriptorCollection GetProperties() => GetProperties(null);
172
-
173
87
  public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
174
-
175
88
  => new PropertyDescriptorCollection(Properties.Select(x => new CustomPropertyDescriptor(x, null)).ToArray());
176
-
177
89
  public object GetPropertyOwner(PropertyDescriptor pd) => this;
178
90
 
179
91
 
180
-
181
-
182
-
183
92
  private class CustomPropertyDescriptor : PropertyDescriptor
184
-
185
93
  {
186
-
187
94
  public override Type ComponentType => Property.Value.GetType();
188
-
189
95
  public override bool IsReadOnly => Property.IsReadOnly;
190
-
191
96
  public override Type PropertyType => Property.Value.GetType();
192
97
 
193
-
194
-
195
98
  public override string Name => Property.Name;
196
-
197
99
  public override string Description => Property.Description;
198
-
199
100
  public override string Category => Property.Category;
200
-
201
101
  public override string DisplayName => Property.Name;
202
-
203
102
  public override bool IsBrowsable => Property.IsVisible;
204
103
 
205
-
206
-
207
104
  private readonly CustomProperty Property;
208
105
 
209
-
210
-
211
106
  public CustomPropertyDescriptor(CustomProperty Property, Attribute[] Attributes)
212
-
213
107
  : base(Property.Name, Attributes) => this.Property = Property;
214
108
 
215
-
216
-
217
109
  public override bool CanResetValue(object component) => true;
218
-
219
110
  public override object GetValue(object component) => Property.Value;
220
-
221
111
  public override void ResetValue(object component) { }
222
-
223
112
  public override void SetValue(object component, object value) => Property.Value = value;
224
-
225
113
  public override bool ShouldSerializeValue(object component) => true;
226
-
227
114
  }
228
-
229
- }
115
+ }
230
-
231
-
232
116
 
233
117
  public class CustomProperty
234
-
235
- {
118
+ {
236
-
237
119
  public string Category { get; set; }
238
-
239
120
  public string Name { get; set; }
240
-
241
121
  public object Value { get; set; }
242
-
243
122
  public string Description { get; set; }
244
-
245
123
  public bool IsReadOnly { get; set; }
246
-
247
124
  public bool IsVisible { get; set; } = true;
248
-
249
125
  public Type Type { get; set; }
250
-
251
- }
126
+ }
252
-
253
-
254
127
 
255
128
  public class CommandInfo
256
-
257
- {
129
+ {
258
-
259
130
  public string CommandName { get; set; }
260
-
261
131
  public string Summery { get; set; }
262
-
263
132
  public string Detail { get; set; }
264
-
265
133
  public int RequestParamNum { get; set; }
266
-
267
134
  public int ResponseParamNum { get; set; }
268
-
269
- }
135
+ }
270
-
271
-
272
136
 
273
137
  public class MainWindowViewModel
274
-
275
- {
138
+ {
276
-
277
139
  public ReactiveProperty<CustomObjectType> CommandProperty { get; } = new ReactiveProperty<CustomObjectType>();
278
-
279
140
  public ObservableCollection<CustomObjectType> CommandList { get; }
280
-
281
141
  public ReactiveCommand TestCommand { get; }
282
142
 
283
-
284
-
285
143
  public MainWindowViewModel()
286
-
287
144
  {
288
-
289
145
  CommandList = new ObservableCollection<CustomObjectType>(
290
-
291
146
  Enumerable.Range(1, 5).Select(x => GetCommandProperty(new CommandInfo
292
-
293
147
  {
294
-
295
148
  CommandName = $"CommandName{x}",
296
-
297
149
  Summery = $"Summery{x}",
298
-
299
150
  Detail = $"Detail{x}",
300
-
301
151
  RequestParamNum = x,
302
-
303
152
  ResponseParamNum = x,
304
-
305
153
  })));
306
154
 
307
-
308
-
309
155
  TestCommand = new ReactiveCommand().WithSubscribe(() =>
310
-
311
- {
156
+ {
312
-
313
157
  if (CommandProperty.Value == null) return;
314
-
315
158
  Debug.WriteLine($"\n{CommandProperty.Value.Name}");
316
-
317
159
  foreach (var property in CommandProperty.Value.Properties)
318
-
319
160
  Debug.WriteLine($"{property.Name}: {property.Value}");
320
-
321
- });
161
+ });
322
-
323
162
  }
324
163
 
325
-
326
-
327
164
  private CustomObjectType GetCommandProperty(CommandInfo info)
328
-
329
165
  {
330
-
331
166
  var description = $"{info.Summery}\n{info.Detail}";
332
-
333
167
  var result = new CustomObjectType
334
-
335
- {
168
+ {
336
-
337
169
  Name = $"{info.CommandName}",
338
-
339
170
  };
340
-
341
171
  result.Properties.Add(new CustomProperty
342
-
343
- {
172
+ {
344
-
345
173
  Category = "CommandInformation",
346
-
347
174
  Name = "CommandName",
348
-
349
175
  Type = typeof(string),
350
-
351
176
  Description = description,
352
-
353
177
  Value = info.CommandName,
354
-
355
- });
178
+ });
356
-
357
179
  result.Properties.Add(new CustomProperty
358
-
359
- {
180
+ {
360
-
361
181
  Category = "CommandInformation",
362
-
363
182
  Name = "AdjustBlock",
364
-
365
183
  Type = typeof(string),
366
-
367
184
  Description = description,
368
-
369
185
  Value = info.CommandName,
370
-
371
- });
186
+ });
372
-
373
187
  result.Properties.Add(new CustomProperty
374
-
375
- {
188
+ {
376
-
377
189
  Category = "CommandInformation",
378
-
379
190
  Name = "AdjustCode",
380
-
381
191
  Type = typeof(string),
382
-
383
192
  Description = description,
384
-
385
193
  Value = info.CommandName,
386
-
387
- });
194
+ });
388
-
389
-
390
195
 
391
196
  for (var i = 0; i < info.RequestParamNum; i++)
392
-
393
- {
197
+ {
394
-
395
198
  result.Properties.Add(new CustomProperty
396
-
397
199
  {
398
-
399
200
  Category = "RequestParameter",
400
-
401
201
  Name = $"S{i}",
402
-
403
202
  Type = typeof(uint),
404
-
405
203
  Description = $"S{i}",
406
-
407
204
  Value = 0,
408
-
409
205
  });
410
-
411
206
  }
412
207
 
413
-
414
-
415
208
  for (var i = 0; i < info.ResponseParamNum; i++)
416
-
417
- {
209
+ {
418
-
419
210
  result.Properties.Add(new CustomProperty
420
-
421
211
  {
422
-
423
212
  Category = "ResponseParameter",
424
-
425
213
  Name = $"R{i}",
426
-
427
214
  Type = typeof(uint),
428
-
429
215
  Description = $"R{i}",
430
-
431
216
  Value = 0,
432
-
433
217
  });
434
-
435
218
  }
436
219
 
437
-
438
-
439
220
  return result;
440
-
441
221
  }
442
-
443
- }
222
+ }
444
-
445
-
446
223
 
447
224
  public partial class MainWindow : Window
448
-
449
- {
225
+ {
450
-
451
226
  public MainWindow() => InitializeComponent();
452
-
453
- }
227
+ }
454
-
455
228
  }
456
-
457
229
  ```