chr
2024-08-07 22beee93f14d042aa184148c53efb79e23416526
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
/*
 *  主要参考:https://blog.csdn.net/lhx527099095/article/details/8061169/ 
 */
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
 
namespace PdmSwPlugin.Common.Control.TreeGrid
{
 
 
    public class TreeGrid : TreeView
    {
        static TreeGrid()
        {
            //ScrollViewer.HorizontalScrollBarVisibilityProperty
            //    .OverrideMetadata(typeof(TreeDataGrid), new FrameworkPropertyMetadata(ScrollBarVisibility.Disabled));
            //ScrollViewer.VerticalScrollBarVisibilityProperty
            //    .OverrideMetadata(typeof(TreeDataGrid), new FrameworkPropertyMetadata(ScrollBarVisibility.Disabled));
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGrid), new FrameworkPropertyMetadata(typeof(TreeGrid)));
        }
 
        #region ColumnMappings DependencyProperty
        public string ColumnMappings
        {
            get { return (string)GetValue(ColumnMappingsProperty); }
            set { SetValue(ColumnMappingsProperty, value); }
        }
        public static readonly DependencyProperty ColumnMappingsProperty =
                DependencyProperty.Register("ColumnMappings", typeof(string), typeof(TreeGrid),
                new PropertyMetadata("", new PropertyChangedCallback(TreeGrid.OnColumnMappingsPropertyChanged)));
 
        private static void OnColumnMappingsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is TreeGrid)
            {
                (obj as TreeGrid).OnColumnMappingsValueChanged();
            }
        }
 
        protected void OnColumnMappingsValueChanged()
        {
            if (!string.IsNullOrEmpty(ColumnMappings))
            {
                ResetMappingColumns(ColumnMappings);
            }
        }
 
        private void ResetMappingColumns(string mapping)
        {
            GridViewColumnCollection items = new GridViewColumnCollection();
            var columns = mapping.Split(new char[] { ';', '|' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var c in columns)
            {
                var index = c.IndexOf(':');
                var title = "";
                var name = "";
                if (index > 0)
                {
                    title = c.Substring(0, index);
                    name = c.Substring(index + 1);
                }
                else
                {
                    title = c;
                    name = c;
                }
 
                DataTemplate temp = null;
                var res = this.FindTreeResource<DataTemplate>(name);
                if (res != null && res is DataTemplate template)
                {
                    temp = template;
                }
                else
                {
                    temp = new DataTemplate();
                    FrameworkElementFactory element = null;
                    if (items.Count == 0)
                    {
                        element = new FrameworkElementFactory(typeof(TreeItemContentControl));
                        element.SetValue(ContentControl.ContentProperty, new Binding(name));
                    }
                    else
                    {
                        element = new FrameworkElementFactory(typeof(TreeGridCell));
                        element.SetValue(ContentControl.ContentProperty, new Binding(name));
                    }
                    temp.VisualTree = element;
                }
                var col = new GridViewColumn
                {
                    Header = title,
                    CellTemplate = temp,
                };
                items.Add(col);
            }
            Columns = items;
        }
        #endregion
 
        #region Columns DependencyProperty
        public GridViewColumnCollection Columns
        {
            get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }
        public static readonly DependencyProperty ColumnsProperty =
                DependencyProperty.Register("Columns", typeof(GridViewColumnCollection), typeof(TreeGrid),
                new PropertyMetadata(null, new PropertyChangedCallback(TreeGrid.OnColumnsPropertyChanged)));
 
        private static void OnColumnsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is TreeGrid)
            {
                (obj as TreeGrid).OnColumnsValueChanged();
            }
        }
 
        protected void OnColumnsValueChanged()
        {
 
        }
        #endregion
 
        #region RowHeight DependencyProperty
        public double RowHeight
        {
            get { return (double)GetValue(RowHeightProperty); }
            set { SetValue(RowHeightProperty, value); }
        }
        public static readonly DependencyProperty RowHeightProperty =
                DependencyProperty.Register("RowHeight", typeof(double), typeof(TreeGrid),
                new PropertyMetadata(30.0, new PropertyChangedCallback(TreeGrid.OnRowHeightPropertyChanged)));
 
        private static void OnRowHeightPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is TreeGrid)
            {
                (obj as TreeGrid).OnRowHeightValueChanged();
            }
        }
 
        protected void OnRowHeightValueChanged()
        {
 
        }
        #endregion
 
        #region ShowCellBorder DependencyProperty
        public bool ShowCellBorder
        {
            get { return (bool)GetValue(ShowCellBorderProperty); }
            set { SetValue(ShowCellBorderProperty, value); }
        }
        public static readonly DependencyProperty ShowCellBorderProperty =
                DependencyProperty.Register("ShowCellBorder", typeof(bool), typeof(TreeGrid),
                new PropertyMetadata(false, new PropertyChangedCallback(TreeGrid.OnShowCellBorderPropertyChanged)));
 
        private static void OnShowCellBorderPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is TreeGrid)
            {
                (obj as TreeGrid).OnShowCellBorderValueChanged();
            }
        }
 
        protected void OnShowCellBorderValueChanged()
        {
 
        }
        #endregion
 
        #region IconStroke DependencyProperty
        public Brush IconStroke
        {
            get { return (Brush)GetValue(IconStrokeProperty); }
            set { SetValue(IconStrokeProperty, value); }
        }
        public static readonly DependencyProperty IconStrokeProperty =
                DependencyProperty.Register("IconStroke", typeof(Brush), typeof(TreeGrid),
                new PropertyMetadata(new SolidColorBrush(Colors.LightGray), new PropertyChangedCallback(TreeGrid.OnIconStrokePropertyChanged)));
 
        private static void OnIconStrokePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is TreeGrid)
            {
                (obj as TreeGrid).OnIconStrokeValueChanged();
            }
        }
 
        protected void OnIconStrokeValueChanged()
        {
 
        }
        #endregion
 
        #region CellBorderBrush DependencyProperty
        public Brush CellBorderBrush
        {
            get { return (Brush)GetValue(CellBorderBrushProperty); }
            set { SetValue(CellBorderBrushProperty, value); }
        }
        public static readonly DependencyProperty CellBorderBrushProperty =
                DependencyProperty.Register("CellBorderBrush", typeof(Brush), typeof(TreeGrid),
                new PropertyMetadata(new SolidColorBrush(Colors.LightGray), new PropertyChangedCallback(TreeGrid.OnCellBorderBrushPropertyChanged)));
 
        private static void OnCellBorderBrushPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is TreeGrid)
            {
                (obj as TreeGrid).OnCellBorderBrushValueChanged();
            }
        }
 
        protected void OnCellBorderBrushValueChanged()
        {
 
        }
        #endregion
 
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TreeGridItem();
        }
 
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is TreeGridItem;
        }
 
        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);
        }
    }
 
    public class TreeGridItem : TreeViewItem
    {
        public event EventHandler IconStateChanged;
        static TreeGridItem()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGridItem), new FrameworkPropertyMetadata(typeof(TreeGridItem)));
        }
 
        public TreeGridItem()
        {
            this.DataContextChanged += TreeGridItem_DataContextChanged;
        }
 
        private void TreeGridItem_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null && e.OldValue is TreeItemData oldTreeData) {
                oldTreeData.VisibleChange -= DataVisiableChange;
            }
            if (DataContext != null && DataContext is TreeItemData treeData)
            {
                this.SetBinding(IsExpandedProperty, new Binding("IsExpanded") { Source = treeData, Mode = BindingMode.TwoWay });
                treeData.VisibleChange += DataVisiableChange;
            }
        }
 
        private void DataVisiableChange(object sender, bool visiable) {
            var sss = visiable;
        }
 
 
        protected override void OnVisualParentChanged(DependencyObject oldParent)
        {
            base.OnVisualParentChanged(oldParent);
        }
 
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TreeGridItem();
        }
 
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is TreeGridItem;
        }
    }
 
    /*
     * https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/GridViewRowPresenter.cs,ace7d38fc902993d
     * GridViewRow里的每个元素,增加了一个默认的Margin,这样在设置边框的时候会比较麻烦,在运行时去掉
     */
    public class TreeGridCell : ContentControl
    {
        static TreeGridCell()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGridCell), new FrameworkPropertyMetadata(typeof(TreeGridCell)));
        }
 
        public TreeGridCell()
        {
            Loaded += TreeGridCell_Loaded;
        }
 
        private void TreeGridCell_Loaded(object sender, RoutedEventArgs e)
        {
            Loaded -= TreeGridCell_Loaded;
            var p = VisualTreeHelper.GetParent(this);
            if (p != null && p is FrameworkElement f && f.Margin.Left > 0)
            {
                f.Margin = new Thickness(0);
            }
        }
    }
 
    public static class TreeHelper
    {
        public static T FindParent<T>(this DependencyObject obj)
        {
            var p = VisualTreeHelper.GetParent(obj);
            if (p == null)
            {
                return default(T);
            }
            if (p is T tt)
            {
                return tt;
            }
            return FindParent<T>(p);
        }
 
        public static IEnumerable<T> FindChild<T>(this DependencyObject obj) where T : DependencyObject
        {
            if (obj == null)
            {
                yield break;
            }
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child == null)
                {
                    continue;
                }
                if (child is T)
                {
                    yield return (T)child;
                }
                else
                {
                    foreach (var c in FindChild<T>(child))
                    {
                        yield return c;
                    }
                }
            }
        }
 
        public static T FindTreeResource<T>(this FrameworkElement obj, string key)
        {
            if (obj == null)
            {
                return default(T);
            }
            var r = obj.TryFindResource(key);
            if (r == null)
            {
                r = Application.Current.TryFindResource(key);
            }
            if (r != null && r is T t)
            {
                return t;
            }
 
            var p = FindParent<FrameworkElement>(obj);
            if (p != null)
            {
                return FindTreeResource<T>(p, key);
            }
            return default(T);
        }
    }
 
    public class LevelToMarginConverter : IValueConverter
    {
        public object Convert(object o, Type type, object parameter, CultureInfo culture)
        {
            return new Thickness((int)o * c_IndentSize, 0, 0, 0);
        }
 
        public object ConvertBack(object o, Type type, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
 
        private const double c_IndentSize = 15.0;
    }
}