質問編集履歴

2

誤記修正

2021/08/10 16:44

投稿

OlivePopeye.net
OlivePopeye.net

スコア26

test CHANGED
File without changes
test CHANGED
@@ -416,10 +416,6 @@
416
416
 
417
417
 
418
418
 
419
- 参考URL:https://living-sun.com/126349-how-to-display-a-dynamic-object-in-property-grid-c-winforms-propertygrid.html
420
-
421
-
422
-
423
419
 
424
420
 
425
421
  ---

1

画像表示がおかしかったので修正

2021/08/10 16:43

投稿

OlivePopeye.net
OlivePopeye.net

スコア26

test CHANGED
File without changes
test CHANGED
@@ -22,380 +22,376 @@
22
22
 
23
23
 
24
24
 
25
+ ![image](edcca26eda19f0c4408715949d53de38.png)
26
+
27
+
28
+
29
+ ### 該当のソースコード
30
+
31
+
32
+
33
+ ```XAML
34
+
35
+ <Window x:Class="SensCmdApp.View.MainWindow"
36
+
37
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
38
+
39
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
40
+
41
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
42
+
43
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
44
+
45
+ xmlns:local="clr-namespace:SensCmdApp.View"
46
+
47
+ mc:Ignorable="d"
48
+
49
+ xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
50
+
51
+ xmlns:rp="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
52
+
53
+ xmlns:vm="clr-namespace:SensCmdApp.ViewModel"
54
+
55
+ xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:model="clr-namespace:SensCmdApp.Model"
56
+
57
+ Title="MainWindow" Height="450" Width="800">
58
+
59
+
60
+
61
+ <Window.DataContext>
62
+
63
+ <vm:MainWindowViewModel />
64
+
65
+ </Window.DataContext>
66
+
67
+
68
+
69
+ <Grid>
70
+
71
+ <Grid.ColumnDefinitions>
72
+
73
+ <ColumnDefinition MinWidth="100" Width="200" />
74
+
75
+ <ColumnDefinition Width="5" />
76
+
77
+ <ColumnDefinition Width="*" />
78
+
79
+ </Grid.ColumnDefinitions>
80
+
81
+
82
+
83
+ <DockPanel Grid.Column="0" LastChildFill="True" >
84
+
85
+ <TreeView ItemsSource="{Binding CommandTree}" DockPanel.Dock="Top" Margin="5,5,0,5">
86
+
87
+
88
+
89
+ <i:Interaction.Triggers>
90
+
91
+ <i:EventTrigger EventName="SelectedItemChanged">
92
+
93
+ <rp:EventToReactiveCommand Command="{Binding SelectionChangedCommand}" />
94
+
95
+ </i:EventTrigger>
96
+
97
+ </i:Interaction.Triggers>
98
+
99
+
100
+
101
+ <TreeView.ItemTemplate>
102
+
103
+ <HierarchicalDataTemplate ItemsSource="{Binding Children}" >
104
+
105
+ <TextBlock Text="{Binding Name}" />
106
+
107
+ </HierarchicalDataTemplate>
108
+
109
+ </TreeView.ItemTemplate>
110
+
111
+
112
+
113
+ </TreeView>
114
+
115
+ </DockPanel>
116
+
117
+
118
+
119
+ <GridSplitter Grid.Column="1" Style="{StaticResource VerticalGridSplitter}" />
120
+
121
+
122
+
123
+ <DockPanel Grid.Column="2" LastChildFill="True">
124
+
125
+ <Button Content="Test" DockPanel.Dock="Bottom" Height="30" />
126
+
127
+ <xctk:PropertyGrid DockPanel.Dock="Bottom" ShowSearchBox="False" ShowSortOptions="False" SelectedObject="{Binding CommandProperty.Value, UpdateSourceTrigger=PropertyChanged}" />
128
+
129
+ </DockPanel>
130
+
131
+ </Grid>
132
+
133
+ </Window>
134
+
25
135
  ```
26
136
 
137
+ ```c#
138
+
139
+ /// CustomProperty/CustomPropertyDescriptor/CustomObjectConverter
140
+
141
+ ///
142
+
143
+ using System;
144
+
145
+ using System.Collections.Generic;
146
+
147
+ using System.Collections.ObjectModel;
148
+
149
+ using System.ComponentModel;
150
+
151
+ using System.Linq;
152
+
153
+
154
+
155
+ namespace SensCmdApp.Model
156
+
157
+ {
158
+
159
+ /// <summary>
160
+
161
+ /// CustomClass (Which is binding to property grid)
162
+
163
+ /// </summary>
164
+
165
+ //[TypeConverter(typeof(CustomObjectConverter))]
166
+
167
+ [TypeConverter(typeof(CustomObjectConverter))]
168
+
169
+ public class CustomObjectType
170
+
171
+ {
172
+
173
+ [Browsable(false)]
174
+
175
+ public string Name { get; set; }
176
+
177
+ [Browsable(false)]
178
+
179
+ public ObservableCollection<CustomProperty> Properties { get; set; } = new ObservableCollection<CustomProperty>();
180
+
181
+ }
182
+
183
+ /// <summary>
184
+
185
+ /// Custom property class
186
+
187
+ /// </summary>
188
+
189
+ public class CustomProperty
190
+
191
+ {
192
+
193
+ public string Category { get; set; } = string.Empty;
194
+
195
+ public string Name { get; set; } = string.Empty;
196
+
197
+ public object Value { get; set; } = null;
198
+
199
+ public string Description { get; set; } = string.Empty;
200
+
201
+ public bool IsReadOnly { get; set; } = false;
202
+
203
+ public bool IsVisible { get; set; } = true;
204
+
205
+ public Type Type { get; set; } = null;
206
+
207
+ }
208
+
209
+ /// <summary>
210
+
211
+ /// Custom PropertyDescriptor
212
+
213
+ /// </summary>
214
+
215
+ public class CustomPropertyDescriptor : PropertyDescriptor
216
+
217
+ {
218
+
219
+ CustomProperty _prop;
220
+
221
+
222
+
223
+ public CustomPropertyDescriptor(CustomProperty Property, Attribute[] Attributes) : base(Property.Name, Attributes)
224
+
225
+ {
226
+
227
+ _prop = Property;
228
+
229
+ }
230
+
231
+
232
+
233
+ #region PropertyDescriptor specific
234
+
235
+ public override bool CanResetValue(object component) => true;
236
+
237
+ public override Type ComponentType => _prop.Value.GetType();
238
+
239
+ public override object GetValue(object component) => _prop.Value;
240
+
241
+ public override string Name => _prop.Name;
242
+
243
+ public override string Description => _prop.Description;
244
+
245
+ public override string Category => _prop.Category;
246
+
247
+ public override string DisplayName => _prop.Name;
248
+
249
+ public override bool IsReadOnly => _prop.IsReadOnly;
250
+
251
+ public override void ResetValue(object component) { /* Have to implement */ }
252
+
253
+ public override bool ShouldSerializeValue(object component) => true;
254
+
255
+ public override void SetValue(object component, object value) => _prop.Value = value;
256
+
257
+ public override Type PropertyType => _prop.Value.GetType();
258
+
259
+ public override bool IsBrowsable => _prop.IsVisible;
260
+
261
+ #endregion
262
+
263
+ }
264
+
265
+
266
+
267
+ public class CustomObjectConverter : ExpandableObjectConverter
268
+
269
+ {
270
+
271
+ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
272
+
273
+ {
274
+
275
+ CustomObjectType obj = value as CustomObjectType;
276
+
277
+ List<CustomProperty> customProps = obj?.Properties.ToList();
278
+
279
+ PropertyDescriptor[] props = new PropertyDescriptor[(customProps == null ? 0 : customProps.Count)];
280
+
281
+ if (customProps != null)
282
+
283
+ {
284
+
285
+ for (int i = 0; i < customProps.Count; i++)
286
+
287
+ {
288
+
289
+ props[i] = new CustomPropertyDescriptor(customProps[i], attributes);
290
+
291
+ }
292
+
293
+ }
294
+
295
+
296
+
27
- ![イメージ説明](ccb39b466ab737d006b079ba08335ff3.png)
297
+ return new PropertyDescriptorCollection(props);
298
+
299
+ }
300
+
301
+ }
302
+
303
+ }
28
304
 
29
305
  ```
30
306
 
31
307
 
32
308
 
33
- ### 該当のソースコード
34
-
35
-
36
-
37
- ```XAML
38
-
39
- <Window x:Class="SensCmdApp.View.MainWindow"
40
-
41
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
42
-
43
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
-
45
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
46
-
47
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
48
-
49
- xmlns:local="clr-namespace:SensCmdApp.View"
50
-
51
- mc:Ignorable="d"
52
-
53
- xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
54
-
55
- xmlns:rp="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
56
-
57
- xmlns:vm="clr-namespace:SensCmdApp.ViewModel"
58
-
59
- xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:model="clr-namespace:SensCmdApp.Model"
60
-
61
- Title="MainWindow" Height="450" Width="800">
62
-
63
-
64
-
65
- <Window.DataContext>
66
-
67
- <vm:MainWindowViewModel />
68
-
69
- </Window.DataContext>
70
-
71
-
72
-
73
- <Grid>
74
-
75
- <Grid.ColumnDefinitions>
76
-
77
- <ColumnDefinition MinWidth="100" Width="200" />
78
-
79
- <ColumnDefinition Width="5" />
80
-
81
- <ColumnDefinition Width="*" />
82
-
83
- </Grid.ColumnDefinitions>
84
-
85
-
86
-
87
- <DockPanel Grid.Column="0" LastChildFill="True" >
88
-
89
- <TreeView ItemsSource="{Binding CommandTree}" DockPanel.Dock="Top" Margin="5,5,0,5">
309
+ ```C#
310
+
311
+ // ~~ 省略 ~~
312
+
313
+
314
+
315
+ public ReactiveProperty<CustomObjectType> CommandProperty { get; set; } = new ReactiveProperty<CustomObjectType>();
316
+
317
+
318
+
319
+ public CustomObjectType GetCommandProperty()
320
+
321
+ {
322
+
323
+ var result = new CustomObjectType();
324
+
325
+
326
+
327
+ try
328
+
329
+ {
330
+
331
+ var cmd = CommandInfo;
332
+
333
+
334
+
335
+ if (CommandInfo == null) { return null; }
336
+
337
+
338
+
339
+ // Command Information
340
+
341
+ var name = $"{cmd.CommandName}";
342
+
343
+ var desc = $"{cmd.Summery}\n{cmd.Detail}";
344
+
345
+
346
+
347
+ result.Name = name;
348
+
349
+ result.Properties.Add(new CustomProperty() { Category = "CommandInformation", Name = "CommandName", Type = typeof(string), Description = desc, Value = cmd.CommandName });
350
+
351
+ result.Properties.Add(new CustomProperty() { Category = "CommandInformation", Name = "AdjustBlock", Type = typeof(string), Description = desc, Value = cmd.CommandName });
352
+
353
+ result.Properties.Add(new CustomProperty() { Category = "CommandInformation", Name = "AdjustCode", Type = typeof(string), Description = desc, Value = cmd.CommandName });
90
354
 
91
355
 
92
356
 
93
- <i:Interaction.Triggers>
94
-
95
- <i:EventTrigger EventName="SelectedItemChanged">
96
-
97
- <rp:EventToReactiveCommand Command="{Binding SelectionChangedCommand}" />
98
-
99
- </i:EventTrigger>
100
-
101
- </i:Interaction.Triggers>
102
-
103
-
104
-
105
- <TreeView.ItemTemplate>
106
-
107
- <HierarchicalDataTemplate ItemsSource="{Binding Children}" >
108
-
109
- <TextBlock Text="{Binding Name}" />
357
+ for (int i = 0; i < cmd.RequestParamNum; i++)
110
-
111
- </HierarchicalDataTemplate>
358
+
112
-
113
- </TreeView.ItemTemplate>
114
-
115
-
116
-
117
- </TreeView>
359
+ {
118
-
119
- </DockPanel>
360
+
120
-
121
-
122
-
123
- <GridSplitter Grid.Column="1" Style="{StaticResource VerticalGridSplitter}" />
124
-
125
-
126
-
127
- <DockPanel Grid.Column="2" LastChildFill="True">
128
-
129
- <Button Content="Test" DockPanel.Dock="Bottom" Height="30" />
130
-
131
- <xctk:PropertyGrid DockPanel.Dock="Bottom" ShowSearchBox="False" ShowSortOptions="False" SelectedObject="{Binding CommandProperty.Value, UpdateSourceTrigger=PropertyChanged}" />
361
+ result.Properties.Add(new CustomProperty() { Category = "RequestParameter", Name = $"S{i}", Type = typeof(uint), Description = $"S{i}", Value = 0 });
362
+
132
-
363
+ }
364
+
365
+
366
+
367
+ for (int i = 0; i < cmd.ResponseParamNum; i++)
368
+
369
+ {
370
+
371
+ result.Properties.Add(new CustomProperty() { Category = "ResponseParameter", Name = $"R{i}", Type = typeof(uint), Description = $"R{i}", Value = 0 });
372
+
373
+ }
374
+
375
+ }
376
+
377
+ catch (Exception)
378
+
379
+ {
380
+
381
+ result = null;
382
+
383
+ }
384
+
385
+
386
+
133
- </DockPanel>
387
+ CommandProperty.Value = result;
134
-
388
+
135
- </Grid>
389
+ return result;
136
-
390
+
137
- </Window>
391
+ }
138
392
 
139
393
  ```
140
394
 
141
- ```c#
142
-
143
- /// CustomProperty/CustomPropertyDescriptor/CustomObjectConverter
144
-
145
- ///
146
-
147
- using System;
148
-
149
- using System.Collections.Generic;
150
-
151
- using System.Collections.ObjectModel;
152
-
153
- using System.ComponentModel;
154
-
155
- using System.Linq;
156
-
157
-
158
-
159
- namespace SensCmdApp.Model
160
-
161
- {
162
-
163
- /// <summary>
164
-
165
- /// CustomClass (Which is binding to property grid)
166
-
167
- /// </summary>
168
-
169
- //[TypeConverter(typeof(CustomObjectConverter))]
170
-
171
- [TypeConverter(typeof(CustomObjectConverter))]
172
-
173
- public class CustomObjectType
174
-
175
- {
176
-
177
- [Browsable(false)]
178
-
179
- public string Name { get; set; }
180
-
181
- [Browsable(false)]
182
-
183
- public ObservableCollection<CustomProperty> Properties { get; set; } = new ObservableCollection<CustomProperty>();
184
-
185
- }
186
-
187
- /// <summary>
188
-
189
- /// Custom property class
190
-
191
- /// </summary>
192
-
193
- public class CustomProperty
194
-
195
- {
196
-
197
- public string Category { get; set; } = string.Empty;
198
-
199
- public string Name { get; set; } = string.Empty;
200
-
201
- public object Value { get; set; } = null;
202
-
203
- public string Description { get; set; } = string.Empty;
204
-
205
- public bool IsReadOnly { get; set; } = false;
206
-
207
- public bool IsVisible { get; set; } = true;
208
-
209
- public Type Type { get; set; } = null;
210
-
211
- }
212
-
213
- /// <summary>
214
-
215
- /// Custom PropertyDescriptor
216
-
217
- /// </summary>
218
-
219
- public class CustomPropertyDescriptor : PropertyDescriptor
220
-
221
- {
222
-
223
- CustomProperty _prop;
224
-
225
-
226
-
227
- public CustomPropertyDescriptor(CustomProperty Property, Attribute[] Attributes) : base(Property.Name, Attributes)
228
-
229
- {
230
-
231
- _prop = Property;
232
-
233
- }
234
-
235
-
236
-
237
- #region PropertyDescriptor specific
238
-
239
- public override bool CanResetValue(object component) => true;
240
-
241
- public override Type ComponentType => _prop.Value.GetType();
242
-
243
- public override object GetValue(object component) => _prop.Value;
244
-
245
- public override string Name => _prop.Name;
246
-
247
- public override string Description => _prop.Description;
248
-
249
- public override string Category => _prop.Category;
250
-
251
- public override string DisplayName => _prop.Name;
252
-
253
- public override bool IsReadOnly => _prop.IsReadOnly;
254
-
255
- public override void ResetValue(object component) { /* Have to implement */ }
256
-
257
- public override bool ShouldSerializeValue(object component) => true;
258
-
259
- public override void SetValue(object component, object value) => _prop.Value = value;
260
-
261
- public override Type PropertyType => _prop.Value.GetType();
262
-
263
- public override bool IsBrowsable => _prop.IsVisible;
264
-
265
- #endregion
266
-
267
- }
268
-
269
-
270
-
271
- public class CustomObjectConverter : ExpandableObjectConverter
272
-
273
- {
274
-
275
- public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
276
-
277
- {
278
-
279
- CustomObjectType obj = value as CustomObjectType;
280
-
281
- List<CustomProperty> customProps = obj?.Properties.ToList();
282
-
283
- PropertyDescriptor[] props = new PropertyDescriptor[(customProps == null ? 0 : customProps.Count)];
284
-
285
- if (customProps != null)
286
-
287
- {
288
-
289
- for (int i = 0; i < customProps.Count; i++)
290
-
291
- {
292
-
293
- props[i] = new CustomPropertyDescriptor(customProps[i], attributes);
294
-
295
- }
296
-
297
- }
298
-
299
-
300
-
301
- return new PropertyDescriptorCollection(props);
302
-
303
- }
304
-
305
- }
306
-
307
- }
308
-
309
- ```
310
-
311
-
312
-
313
- ```C#
314
-
315
- // ~~ 省略 ~~
316
-
317
-
318
-
319
- public ReactiveProperty<CustomObjectType> CommandProperty { get; set; } = new ReactiveProperty<CustomObjectType>();
320
-
321
-
322
-
323
- public CustomObjectType GetCommandProperty()
324
-
325
- {
326
-
327
- var result = new CustomObjectType();
328
-
329
-
330
-
331
- try
332
-
333
- {
334
-
335
- var cmd = CommandInfo;
336
-
337
-
338
-
339
- if (CommandInfo == null) { return null; }
340
-
341
-
342
-
343
- // Command Information
344
-
345
- var name = $"{cmd.CommandName}";
346
-
347
- var desc = $"{cmd.Summery}\n{cmd.Detail}";
348
-
349
-
350
-
351
- result.Name = name;
352
-
353
- result.Properties.Add(new CustomProperty() { Category = "CommandInformation", Name = "CommandName", Type = typeof(string), Description = desc, Value = cmd.CommandName });
354
-
355
- result.Properties.Add(new CustomProperty() { Category = "CommandInformation", Name = "AdjustBlock", Type = typeof(string), Description = desc, Value = cmd.CommandName });
356
-
357
- result.Properties.Add(new CustomProperty() { Category = "CommandInformation", Name = "AdjustCode", Type = typeof(string), Description = desc, Value = cmd.CommandName });
358
-
359
-
360
-
361
- for (int i = 0; i < cmd.RequestParamNum; i++)
362
-
363
- {
364
-
365
- result.Properties.Add(new CustomProperty() { Category = "RequestParameter", Name = $"S{i}", Type = typeof(uint), Description = $"S{i}", Value = 0 });
366
-
367
- }
368
-
369
-
370
-
371
- for (int i = 0; i < cmd.ResponseParamNum; i++)
372
-
373
- {
374
-
375
- result.Properties.Add(new CustomProperty() { Category = "ResponseParameter", Name = $"R{i}", Type = typeof(uint), Description = $"R{i}", Value = 0 });
376
-
377
- }
378
-
379
- }
380
-
381
- catch (Exception)
382
-
383
- {
384
-
385
- result = null;
386
-
387
- }
388
-
389
-
390
-
391
- CommandProperty.Value = result;
392
-
393
- return result;
394
-
395
- }
396
-
397
- ```
398
-
399
395
 
400
396
 
401
397
  ### 試したこと