-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHelper.cs
436 lines (381 loc) · 17.3 KB
/
Helper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
using System;
using System.Text;
using System.Drawing;
using DevExpress.Xpo;
using System.ComponentModel;
using DevExpress.Xpo.Metadata;
using DevExpress.Data.Filtering;
using System.Collections.Generic;
using DevExpress.XtraEditors.Controls;
using DevExpress.Xpo.Metadata.Helpers;
using DevExpress.XtraEditors.Container;
using DevExpress.XtraEditors.Filtering;
using DevExpress.XtraEditors.Repository;
using DevExpress.Data.Filtering.Helpers;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace DXSample {
[ToolboxItem(true)]
public class FilteredXPComponent : ComponentEditorContainer, IFilteredComponent {
FilteredXPComponentMessageFilter Filter;
public FilteredXPComponent()
: base() {
Filter = new FilteredXPComponentMessageFilter();
Filter.OnShowWindow += OnShowWindow;
Application.AddMessageFilter(Filter);
}
private XPCollection source;
public XPCollection Source {
get { return source; }
set {
if (ReferenceEquals(source, value)) return;
source = value;
if (isInitializing) return;
PopulateColumns();
RaisePropertiesChanged();
}
}
private void PopulateColumns() {
if (columns.Count > 0) return;
PopulateColumnsFromDisplayableProperties();
}
private void PopulateColumnsFromDisplayableProperties() {
string[] properties = source.DisplayableProperties.Split(';');
foreach (string property in properties)
if (property.Contains("!")) CreateColumnFromPropertyDescriptor(property);
else if (property.Contains(".")) columns.Add(CreateColumnFromNestedProperty(property));
else columns.Add(CreateColumnFromXMember(property));
}
private void CreateColumnFromPropertyDescriptor(string property) {
string[] temp = property.Split(new char[] { '!' },
StringSplitOptions.RemoveEmptyEntries);
FilterColumnProperties props;
if (temp.Length == 1)
props = ParsePropertyPath(temp[0]);
else
props = ParsePropertyPath(string.Format("{0}.!Key", temp[0]));
props.FieldName = property;
columns.Add(props);
}
private FilterColumnProperties ParsePropertyPath(string path) {
if (path.Contains(".")) return CreateColumnFromNestedProperty(path);
else return CreateColumnFromXMember(path);
}
private FilterColumnProperties CreateColumnFromXMember(string property) {
XPMemberInfo member = source.ObjectClassInfo.GetMember(property);
return CreateFilterColumnProperties(property, member.MemberType, member.DisplayName);
}
private FilterColumnProperties CreateColumnFromNestedProperty(string property) {
XPTypeInfo member = source.ObjectClassInfo;
string displayName = ProcessNestedProperty(ref property, ref member);
return CreateFilterColumnProperties(property, ((XPMemberInfo)member).MemberType,
displayName);
}
FilterColumnProperties CreateFilterColumnProperties(string property, Type memberType,
string displayName) {
if (string.IsNullOrEmpty(displayName))
displayName = property;
if (Site != null) {
IDesignerHost host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host != null) {
FilterColumnProperties result = host.CreateComponent(typeof(FilterColumnProperties))
as FilterColumnProperties;
if (result != null) {
result.FieldName = property;
result.DataType = memberType;
result.Caption = displayName;
return result;
}
}
}
return new FilterColumnProperties(property, memberType, displayName);
}
private string ProcessNestedProperty(ref string property, ref XPTypeInfo member) {
StringBuilder displayName = new StringBuilder();
StringBuilder path = new StringBuilder();
string[] elements = property.Split('.');
for (int i = 0; i < elements.Length; i++) {
member = GetNestedMemberInfo(elements[i], member);
string format = i < elements.Length - 1 ? "{0}." : "{0}";
string dn = ((XPMemberInfo)member).DisplayName;
displayName.AppendFormat(format, string.IsNullOrEmpty(dn) ?
((XPMemberInfo)member).Name : dn);
path.AppendFormat(format, ((XPMemberInfo)member).Name);
}
property = path.ToString();
return displayName.ToString();
}
private XPMemberInfo GetNestedMemberInfo(string element, XPTypeInfo member) {
if (member is XPClassInfo) return ((XPClassInfo)member).GetMember(element);
else return GetNestedMemberInfo(ref element, (XPMemberInfo)member);
}
private XPMemberInfo GetNestedMemberInfo(ref string element, XPMemberInfo member) {
XPDictionary dict = ((IXPDictionaryProvider)source).Dictionary;
XPClassInfo cInfo = dict.GetClassInfo(member.MemberType);
if (element == "!Key") element = cInfo.KeyProperty.Name;
return cInfo.GetMember(element);
}
private List<FilterColumnProperties> columns = new List<FilterColumnProperties>();
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<FilterColumnProperties> Columns { get { return columns; } }
#region IFilteredComponent Members
public IBoundPropertyCollection CreateFilterColumnCollection() {
HelperFilterColumnCollection result = new HelperFilterColumnCollection(this);
result.CustomFilterColumnEditor += new CustomFilterColumnEditorEventHandler(OnCustomFilterColumnEditor);
result.CreateColumns();
result.CustomFilterColumnEditor -= new CustomFilterColumnEditorEventHandler(OnCustomFilterColumnEditor);
return result;
}
private void OnCustomFilterColumnEditor(object sender, CustomHelperFilterColumnEditorEventArgs e) {
RaiseCustomFilterColumnEditor(e);
}
private static readonly object fCustomFilterColumnEditor = new object();
public event CustomFilterColumnEditorEventHandler CustomFilterColumnEditor {
add { Events.AddHandler(fCustomFilterColumnEditor, value); }
remove { Events.RemoveHandler(fCustomFilterColumnEditor, value); }
}
private void RaiseCustomFilterColumnEditor(CustomHelperFilterColumnEditorEventArgs args) {
CustomFilterColumnEditorEventHandler handler = Events[fCustomFilterColumnEditor] as CustomFilterColumnEditorEventHandler;
if (handler != null) handler(this, args);
}
private EventHandler propertiesChanged;
public event EventHandler PropertiesChanged {
add { propertiesChanged += value; }
remove { propertiesChanged -= value; }
}
private void RaisePropertiesChanged() {
if (propertiesChanged != null)
propertiesChanged(this, EventArgs.Empty);
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CriteriaOperator RowCriteria {
get {
if (source == null) return null;
return source.Criteria;
}
set {
if (ReferenceEquals(source.Criteria, value)) return;
source.Criteria = value;
RaiseRowFilterChanged();
}
}
private EventHandler rowFilterChanged;
public event EventHandler RowFilterChanged {
add { rowFilterChanged += value; }
remove { rowFilterChanged -= value; }
}
private void RaiseRowFilterChanged() {
if (rowFilterChanged != null)
rowFilterChanged(this, EventArgs.Empty);
}
#endregion
protected override ComponentEditorContainerHelper CreateHelper() {
return new FilteredXPComponentContainerHelper(this);
}
private bool isInitializing = false;
public override void BeginInit() {
isInitializing = true;
base.BeginInit();
}
public override void EndInit() {
isInitializing = false;
RaisePropertiesChanged();
base.EndInit();
}
public void AddColumn(FilterColumnProperties col) {
Columns.Add(col);
RaisePropertiesChanged();
}
public void AdddColumns(params FilterColumnProperties[] columnsToAdd) {
Columns.AddRange(columnsToAdd);
RaisePropertiesChanged();
}
void OnShowWindow(object sender, EventArgs e) {
EditorHelper.InitializePosponedRespositories();
Filter.OnShowWindow -= OnShowWindow;
Application.RemoveMessageFilter(Filter);
Filter = null;
}
}
public class FilteredXPComponentContainerHelper : ComponentEditorContainerHelper {
public FilteredXPComponentContainerHelper(FilteredXPComponent container) : base(container) { }
protected override void RaiseInvalidValueException(InvalidValueExceptionEventArgs e) { }
protected override void RaiseValidatingEditor(BaseContainerValidateEditorEventArgs va) { }
}
public class HelperFilterColumnCollection : FilterColumnCollection {
private FilteredXPComponent filteredComponent;
public HelperFilterColumnCollection(FilteredXPComponent filteredComponent) {
this.filteredComponent = filteredComponent;
}
internal void CreateColumns() {
foreach (FilterColumnProperties properties in filteredComponent.Columns)
if (IsColumnForFilter(properties))
Add(new HelperFilterColumn(properties));
}
private bool IsColumnForFilter(FilterColumnProperties properties) {
if (properties.Editor == null) {
CustomHelperFilterColumnEditorEventArgs args = new CustomHelperFilterColumnEditorEventArgs(properties);
RaiseCustomFilterColumnEditor(args);
properties.Editor = args.Editor;
}
if (properties.DataType == null && filteredComponent.Source != null) {
PropertyDescriptor property = ((ITypedList)filteredComponent.Source).GetItemProperties(null).Find(properties.FieldName, false);
if (property != null)
properties.DataType = property.PropertyType;
}
return properties.Editor != null || properties.DataType == typeof(string) ||
properties.DataType == typeof(short) || properties.DataType == typeof(int) ||
properties.DataType == typeof(long) || properties.DataType == typeof(decimal) ||
properties.DataType == typeof(double) || properties.DataType == typeof(float) ||
properties.DataType == typeof(DateTime) || properties.DataType == typeof(bool);
}
public event CustomFilterColumnEditorEventHandler CustomFilterColumnEditor;
private void RaiseCustomFilterColumnEditor(CustomHelperFilterColumnEditorEventArgs arg) {
if (CustomFilterColumnEditor != null) CustomFilterColumnEditor(this, arg);
}
}
public class HelperFilterColumn : FilterColumn {
private FilterColumnProperties properties;
public HelperFilterColumn(FilterColumnProperties properties) {
this.properties = properties;
}
public override FilterColumnClauseClass ClauseClass {
get {
if (properties.Editor == null) return GetClauseByType();
else return GetClauseByEditor();
}
}
private FilterColumnClauseClass GetClauseByType() {
if (ColumnType == typeof(Image) || ColumnType == typeof(Bitmap) ||
ColumnType == typeof(byte[]))
return FilterColumnClauseClass.Blob;
else if (ColumnType == typeof(string))
return FilterColumnClauseClass.String;
else return FilterColumnClauseClass.Generic;
}
private FilterColumnClauseClass GetClauseByEditor() {
if (IsBlobEditor()) return FilterColumnClauseClass.Blob;
else if (IsLookUpEditor()) return FilterColumnClauseClass.Lookup;
else if (IsTextEditor()) return FilterColumnClauseClass.String;
else return FilterColumnClauseClass.Generic;
}
private bool IsTextEditor() {
return ColumnEditor is RepositoryItemTextEdit ||
ColumnEditor is RepositoryItemMemoEdit;
}
private bool IsLookUpEditor() {
return ColumnEditor is RepositoryItemLookUpEdit ||
ColumnEditor is RepositoryItemGridLookUpEdit;
}
private bool IsBlobEditor() {
return ColumnEditor is RepositoryItemPictureEdit ||
ColumnEditor is RepositoryItemImageEdit;
}
public override string ColumnCaption {
get { return properties.Caption; ; }
}
public override RepositoryItem ColumnEditor {
get {
if (properties.Editor == null) CreateEditor();
return properties.Editor;
}
}
private void CreateEditor() {
switch (ClauseClass) {
case FilterColumnClauseClass.Generic: CreateGenericEditor(); break;
case FilterColumnClauseClass.String:
properties.Editor = new RepositoryItemTextEdit();
break;
}
}
private void CreateGenericEditor() {
if (ColumnType == typeof(int) || ColumnType == typeof(decimal) ||
ColumnType == typeof(short) || ColumnType == typeof(long) ||
ColumnType == typeof(float) || ColumnType == typeof(double))
properties.Editor = new RepositoryItemSpinEdit();
else if (ColumnType == typeof(DateTime))
properties.Editor = new RepositoryItemDateEdit();
else if (ColumnType == typeof(bool))
properties.Editor = new RepositoryItemCheckEdit();
else properties.Editor = new RepositoryItemTextEdit();
}
public override Type ColumnType {
get { return properties.DataType; }
}
public override string FieldName {
get { return properties.FieldName; }
}
public override Image Image {
get { return properties.Image; }
}
}
public delegate void CustomFilterColumnEditorEventHandler(object sender, CustomHelperFilterColumnEditorEventArgs e);
public class CustomHelperFilterColumnEditorEventArgs : EventArgs {
public CustomHelperFilterColumnEditorEventArgs(FilterColumnProperties column) { fColumn = column; }
private FilterColumnProperties fColumn;
public FilterColumnProperties Column { get { return fColumn; } }
private RepositoryItem fEditor;
public RepositoryItem Editor {
get { return fEditor; }
set { fEditor = value; }
}
}
[ToolboxItem(false), DesignTimeVisible(false)]
public class FilterColumnProperties :Component {
public FilterColumnProperties() { }
public FilterColumnProperties(string fieldName, Type type, string caption) {
this.fieldName = fieldName;
this.dataType = type;
if (string.IsNullOrEmpty(caption))
this.caption = fieldName;
else this.caption = caption;
}
private string caption;
[Localizable(true)]
public string Caption {
get { return caption; }
set { caption = value; }
}
private string fieldName;
public string FieldName {
get { return fieldName; }
set { fieldName = value; }
}
private Type dataType;
[Browsable(false)]
public Type DataType {
get { return dataType; }
set { dataType = value; }
}
private RepositoryItem editor;
public RepositoryItem Editor {
get { return editor; }
set { editor = value; }
}
private Image image;
public Image Image {
get { return image; }
set { image = value; }
}
}
public class FilteredXPComponentMessageFilter :IMessageFilter {
const int WM_SHOWWINDOW = 0x18;
EventHandler fOnShowWindow;
public event EventHandler OnShowWindow {
add { fOnShowWindow += value; }
remove { fOnShowWindow -= value; }
}
void RaiseOnShowWindow() {
if (fOnShowWindow != null)
fOnShowWindow(this, EventArgs.Empty);
}
#region IMessageFilter Members
bool IMessageFilter.PreFilterMessage(ref Message m) {
RaiseOnShowWindow();
return false;
}
#endregion
}
}