Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GBT/HeuristicLab.Core.Views/3.3/TypeSelector.cs @ 12495

Last change on this file since 12495 was 12495, checked in by gkronber, 9 years ago

#2261: merged trunk changes to branch
r12494
#2403: added a null check in the MatlabParameterVectorEvaluator to prevent exceptions when clearstate is called


r12493
#2369: added support for squared errors and relative errors to error-characteristic-curve view


r12492
#2392: implemented PearsonsRCalculator to fix incorrect correlation values in the correlation matrix.


r12491
#2402 don't set task state to waiting when it fails


r12490
#2401 added missing Mono.Cecil plugin dependency


r12488
#2400 - Interfaces for Capaciated-, PickupAndDelivery- and TimeWindowed-ProblemInstances now specify an additional penalty parameter to set the current penalty factor for the constraint relaxation. - The setter of the penalty-property in ...


r12485
#2374 made RegressionSolution and ClassificationSolution non-abstract


r12482
#2320: Fixed warnings in unit test solutions introduced in r12420 by marking methods as obsolete.


r12481
#2320: Fixed AfterDeserialization of GEArtifialAntEvaluator.


r12480
#2320: Fixed error in symbolicexpressiontree crossover regarding the wiring of lookup parameters if persisted file is loaded.


r12479
#2397 moved GeoIP project into ExtLibs


r12478
#2329 fixed bug in simple code editor


r12476
#2331 removed outdated plugins


r12475
#2368 fixed compile warnings


r12474
#2399 worked on Mono project prepare script


r12473
#2329 added a simple code editor for Linux


r12472
#2399 - fixed MathJax.js file name - worked on Mono project prepare script


r12471
#2399 worked on Mono project prepare script


r12470
#2399 fixed pre-build events in project files


r12465
#2399 worked on mono project prepare script


r12464
#2399 added patch to project


r12463
#2399 fixed EPPlus so that it compiles on Linux


r12461
#2398: Skip root and start symbols when calculating impacts and replacement values in the pruning operators.


r12458
#2354 show label when no data is displayed and don't show the legend


r12457
#2353 removed duplicated call to Any() in Hive Status page


r12456
#2368 fixed modifier


r12455
#2368 added support in persistence for typecaches in streams


r12445
#2394: Changed Web.config compilation from debug to release to force script bundling. Changed history loading type from lazy to eager loading to increase performance. Fixed "getCoreStatus" typo in statusCtrl.js


r12443
#2394: Fixed UserTaskQuery and GetStatusHistory in the WebApp.Status plugin


r12442
#2394 added nuget folders to svn ignore list


r12435
#2394: Improved PluginManager and updated hive status monitor.


r12434
#2396 added symbolic expression tree formatter for C#


r12433
#2395: Minor change in DoubleValue.GetValue.


r12432
#2395 Use simple round-trip format for doubles because G17 prints some strange numbers (20.22 to 20.219999999999999999). Some accuracy can still be lost on 64bit machines, but should be very rare and minimal. double.MaxValue can still be pa...


r12431
#2395 Fixed parsing issues by using the G17 format.


r12430
#2394 added missing package config


r12429
#2394 added missing package config


r12428
#2394 added web app and status page to trunk


r12424
#2320: Adapted plugin file and updated project file of SymbolicExpressionTreeEncoding.


r12422
#2320: Merged the encoding class and all accompanying changes in the trunk.


r12401
#2387 Fixed a bug where the automatic selection of the first element behaved differently for the NewItemDialog.


r12400
#2387 Forgot to commit a file.


r12399
#2387 - Added context-menu for expanding and collapsing tree-nodes. - Improve response time when expanding/collapsing all nodes for TypeSelector and NewItemDialog.


r12398
#2387 - Added clearSearch-button in TypeSelector. - Adapted behavior of TypeSelector and NewItemDialog that a selected node stays selected as long as it matches the search criteria.


r12397
#2387 - Adapted behavior of the matching in the TypeSelector that it behave the same as the NewItemDialog. The search string is tokenized by space and matches if all tokens are contained, (eg. "Sym Reg" matches "SymbolicRegression...")...


r12393
#2025 - Removed Expand/CollapseAll buttons. - Removed cycling of items.


r12392
#2386: Updated GetHashCode method in the EnumerableBoolEqualityComparer.


  • Property svn:mergeinfo set to (toggle deleted branches)
    /stable/HeuristicLab.Core.Views/3.3/TypeSelector.csmergedeligible
    /trunk/sources/HeuristicLab.Core.Views/3.3/TypeSelector.csmergedeligible
    /branches/CloningRefactoring/HeuristicLab.Core.Views/3.3/TypeSelector.cs4656-4721
    /branches/DataAnalysis Refactoring/HeuristicLab.Core.Views/3.3/TypeSelector.cs5471-5808
    /branches/DataAnalysis SolutionEnsembles/HeuristicLab.Core.Views/3.3/TypeSelector.cs5815-6180
    /branches/DataAnalysis/HeuristicLab.Core.Views/3.3/TypeSelector.cs4458-4459,​4462,​4464
    /branches/DataPreprocessing/HeuristicLab.Core.Views/3.3/TypeSelector.cs10085-11101
    /branches/GP.Grammar.Editor/HeuristicLab.Core.Views/3.3/TypeSelector.cs6335
    /branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Core.Views/3.3/TypeSelector.cs5060
    /branches/NET40/sources/HeuristicLab.Core.Views/3.3/TypeSelector.cs5138-5162
    /branches/ParallelEngine/HeuristicLab.Core.Views/3.3/TypeSelector.cs5175-5192
    /branches/QAPAlgorithms/HeuristicLab.Core.Views/3.3/TypeSelector.cs6350-6627
    /branches/Restructure trunk solution/HeuristicLab.Core.Views/3.3/TypeSelector.cs6828
    /branches/SuccessProgressAnalysis/HeuristicLab.Core.Views/3.3/TypeSelector.cs5370-5682
    /branches/Trunk/HeuristicLab.Core.Views/3.3/TypeSelector.cs6829-6865
    /branches/VNS/HeuristicLab.Core.Views/3.3/TypeSelector.cs5594-5752
    /branches/histogram/HeuristicLab.Core.Views/3.3/TypeSelector.cs5959-6341
File size: 19.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Reflection;
27using System.Text;
28using System.Windows.Forms;
29using HeuristicLab.Common;
30using HeuristicLab.PluginInfrastructure;
31
32namespace HeuristicLab.Core.Views {
33  public partial class TypeSelector : UserControl {
34    protected List<TreeNode> treeNodes;
35    protected string currentSearchString;
36    protected TypeSelectorDialog typeSelectorDialog;
37
38    protected IEnumerable<Type> baseTypes;
39    public IEnumerable<Type> BaseTypes {
40      get { return baseTypes; }
41    }
42    protected bool showNotInstantiableTypes;
43    public bool ShowNotInstantiableTypes {
44      get { return showNotInstantiableTypes; }
45    }
46    protected bool showGenericTypes;
47    public bool ShowGenericTypes {
48      get { return showGenericTypes; }
49    }
50    public string Caption {
51      get { return typesGroupBox.Text; }
52      set {
53        if (InvokeRequired)
54          Invoke(new Action<string>(delegate(string s) { Caption = s; }), value);
55        else
56          typesGroupBox.Text = value;
57      }
58    }
59    public TreeView TypesTreeView {
60      get { return typesTreeView; }
61    }
62    protected Type selectedType;
63    public Type SelectedType {
64      get { return selectedType; }
65      private set {
66        if (value != selectedType) {
67          selectedType = value;
68          OnSelectedTypeChanged();
69        }
70      }
71    }
72
73    public TypeSelector() {
74      InitializeComponent();
75      treeNodes = new List<TreeNode>();
76      currentSearchString = string.Empty;
77      selectedType = null;
78    }
79
80    protected override void Dispose(bool disposing) {
81      if (disposing) {
82        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
83        if (components != null) components.Dispose();
84      }
85      base.Dispose(disposing);
86    }
87
88    public virtual void Configure(Type baseType, bool showNotInstantiableTypes, bool showGenericTypes) {
89      Configure(baseType, showNotInstantiableTypes, showGenericTypes, (t) => true);
90    }
91
92    public virtual void Configure(Type baseType, bool showNotInstantiableTypes, bool showGenericTypes, Func<Type, bool> typeCondition) {
93      Configure(new List<Type>() { baseType }, showNotInstantiableTypes, showGenericTypes, true, typeCondition);
94    }
95
96    public virtual void Configure(IEnumerable<Type> baseTypes, bool showNotInstantiableTypes, bool showGenericTypes, bool assignableToAllTypes) {
97      Configure(baseTypes, showNotInstantiableTypes, showGenericTypes, assignableToAllTypes, (t) => { return true; });
98    }
99
100    public virtual void Configure(IEnumerable<Type> baseTypes, bool showNotInstantiableTypes, bool showGenericTypes, bool assignableToAllTypes, Func<Type, bool> typeCondition) {
101      if (baseTypes == null) throw new ArgumentNullException();
102      if (InvokeRequired)
103        Invoke(new Action<IEnumerable<Type>, bool, bool, bool, Func<Type, bool>>(Configure), baseTypes, showNotInstantiableTypes, showGenericTypes, assignableToAllTypes, typeCondition);
104      else {
105        this.baseTypes = baseTypes;
106        this.showNotInstantiableTypes = showNotInstantiableTypes;
107        this.showGenericTypes = showGenericTypes;
108        bool selectedTypeFound = false;
109
110        typeParametersSplitContainer.Panel2Collapsed = !showGenericTypes;
111
112        TreeNode selectedNode = typesTreeView.SelectedNode;
113        typesTreeView.Nodes.Clear();
114        treeNodes.Clear();
115
116        imageList.Images.Clear();
117        imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Class);      // default icon
118        imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Namespace);  // plugins
119        imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Interface);  // interfaces
120        imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Template);   // generic types
121        // additional dictionary for image indexes as imageList.ContainsKey and imageList.IndexOfKey are very slow!
122        var imageNames = new Dictionary<string, int>();
123
124        var plugins = from p in ApplicationManager.Manager.Plugins
125                      orderby p.Name, p.Version ascending
126                      select p;
127        foreach (IPluginDescription plugin in plugins) {
128          TreeNode pluginNode = new TreeNode();
129          pluginNode.Text = string.Format("{0} {1}.{2}", plugin.Name, plugin.Version.Major, plugin.Version.Minor);
130          pluginNode.ImageIndex = 1;
131          pluginNode.SelectedImageIndex = pluginNode.ImageIndex;
132          pluginNode.Tag = plugin;
133
134          var types = from t in ApplicationManager.Manager.GetTypes(BaseTypes, plugin, !ShowNotInstantiableTypes, ShowGenericTypes, assignableToAllTypes)
135                      where typeCondition(t)
136                      orderby t.Name ascending
137                      select t;
138          foreach (Type type in types) {
139            bool valid = (ShowNotInstantiableTypes || type.GetConstructor(Type.EmptyTypes) != null); //check for public default ctor
140            if (valid) {
141              TreeNode typeNode = new TreeNode();
142              string name = ItemAttribute.GetName(type);
143              typeNode.Text = name != null ? name : type.GetPrettyName();
144              typeNode.ImageIndex = 0;
145              if (type.IsInterface) typeNode.ImageIndex = 2;
146              else if (type.ContainsGenericParameters) typeNode.ImageIndex = 3;
147              else if (imageNames.ContainsKey(type.FullName)) typeNode.ImageIndex = imageNames[type.FullName];
148              else {
149                var image = ItemAttribute.GetImage(type);
150                if (image != null) {
151                  imageList.Images.Add(image);
152                  typeNode.ImageIndex = imageList.Images.Count - 1;
153                  imageNames.Add(type.FullName, imageList.Images.Count - 1);
154                }
155              }
156              typeNode.SelectedImageIndex = typeNode.ImageIndex;
157              typeNode.Tag = type;
158              pluginNode.Nodes.Add(typeNode);
159              if (type.Equals(selectedType)) selectedTypeFound = true;
160            }
161          }
162          if (pluginNode.Nodes.Count > 0)
163            treeNodes.Add(pluginNode);
164        }
165        if (!selectedTypeFound) SelectedType = null;
166        foreach (TreeNode node in treeNodes)
167          typesTreeView.Nodes.Add((TreeNode)node.Clone());
168        RestoreSelectedNode(selectedNode);
169        Filter(searchTextBox.Text);
170
171        UpdateTypeParameters();
172      }
173    }
174
175    public virtual void Filter(string searchString) {
176      if (InvokeRequired)
177        Invoke(new Action<string>(Filter), searchString);
178      else {
179        searchString = searchString.ToLower();
180        TreeNode selectedNode = typesTreeView.SelectedNode;
181
182        if (!searchString.Contains(currentSearchString)) {
183          typesTreeView.BeginUpdate();
184          // expand search -> restore all tree nodes
185          typesTreeView.Nodes.Clear();
186          foreach (TreeNode node in treeNodes)
187            typesTreeView.Nodes.Add((TreeNode)node.Clone());
188          typesTreeView.EndUpdate();
189        }
190
191        // remove nodes
192        typesTreeView.BeginUpdate();
193        var searchTokens = searchString.Split(' ');
194        int i = 0;
195        while (i < typesTreeView.Nodes.Count) {
196          var node = typesTreeView.Nodes[i];
197          bool remove = FilterNode(node, searchTokens);
198          if (remove)
199            typesTreeView.Nodes.RemoveAt(i);
200          else i++;
201        }
202        typesTreeView.EndUpdate();
203        currentSearchString = searchString;
204
205        // select first item
206        typesTreeView.BeginUpdate();
207        var firstNode = typesTreeView.Nodes.Count > 0 ? typesTreeView.Nodes[0] : null;
208        while (firstNode != null && !(firstNode.Tag is Type))
209          firstNode = firstNode.NextVisibleNode;
210        if (firstNode != null)
211          typesTreeView.SelectedNode = firstNode;
212
213        if (typesTreeView.Nodes.Count == 0) {
214          SelectedType = null;
215          typesTreeView.Enabled = false;
216        } else {
217          SetTreeNodeVisibility();
218          typesTreeView.Enabled = true;
219        }
220        typesTreeView.EndUpdate();
221
222        RestoreSelectedNode(selectedNode);
223        UpdateDescription();
224      }
225    }
226
227    private bool FilterNode(TreeNode node, string[] searchTokens) {
228      if (node.Tag is IPluginDescription) { // Plugin node
229        int i = 0;
230        while (i < node.Nodes.Count) {
231          bool remove = FilterNode(node.Nodes[i], searchTokens);
232          if (remove)
233            node.Nodes.RemoveAt(i);
234          else i++;
235        }
236        return node.Nodes.Count == 0;
237      } if (node.Tag is Type) { // Type node
238        var text = node.Text;
239        if (searchTokens.Any(searchToken => !text.ToLower().Contains(searchToken))) {
240          var typeTag = (Type)node.Tag;
241          if (typeTag == SelectedType) {
242            SelectedType = null;
243            typesTreeView.SelectedNode = null;
244          }
245          return true;
246        }
247        return false;
248      }
249      throw new InvalidOperationException("Encountered neither a plugin nor a type node during tree traversal.");
250    }
251
252    public virtual object CreateInstanceOfSelectedType(params object[] args) {
253      if (SelectedType == null)
254        throw new InvalidOperationException("No type selected.");
255      else
256        return Activator.CreateInstance(SelectedType, args);
257    }
258
259    protected virtual void UpdateTypeParameters() {
260      typeParametersListView.Items.Clear();
261      if ((SelectedType == null) || !SelectedType.ContainsGenericParameters) {
262        typeParametersGroupBox.Enabled = false;
263        typeParametersSplitContainer.Panel2Collapsed = true;
264      } else {
265        typeParametersGroupBox.Enabled = true;
266        typeParametersSplitContainer.Panel2Collapsed = false;
267        setTypeParameterButton.Enabled = false;
268
269        foreach (Type param in SelectedType.GetGenericArguments()) {
270          if (param.IsGenericParameter) {
271            ListViewItem item = new ListViewItem();
272            item.Text = param.Name;
273
274            item.ToolTipText = "Constraints:";
275            Type[] constraints = param.GetGenericParameterConstraints();
276            if (constraints.Length == 0) {
277              item.ToolTipText += " none";
278            } else {
279              foreach (Type constraint in constraints)
280                item.ToolTipText += " " + constraint.GetPrettyName();
281            }
282
283            item.Tag = param;
284            typeParametersListView.Items.Add(item);
285          }
286        }
287        typeParametersListView.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
288      }
289    }
290
291    protected virtual void SetTypeParameter() {
292      if (typeSelectorDialog == null) {
293        typeSelectorDialog = new TypeSelectorDialog();
294        typeSelectorDialog.Caption = "Select Type of Generic Type Parameter";
295      }
296      Type param = typeParametersListView.SelectedItems[0].Tag as Type;
297      Type[] constraints = param.GetGenericParameterConstraints();
298      bool showNotInstantiableTypes = !param.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint);
299      typeSelectorDialog.TypeSelector.Configure(constraints, showNotInstantiableTypes, true, true);
300
301      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
302        Type selected = typeSelectorDialog.TypeSelector.SelectedType;
303        Type[] parameters = SelectedType.GetGenericArguments();
304        parameters[param.GenericParameterPosition] = selected;
305        SelectedType = SelectedType.GetGenericTypeDefinition().MakeGenericType(parameters);
306
307        typeParametersListView.SelectedItems[0].Text = param.Name + ": " + selected.GetPrettyName();
308        typeParametersListView.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
309      }
310    }
311
312    protected virtual void UpdateDescription() {
313      descriptionTextBox.Text = string.Empty;
314
315      if (typesTreeView.SelectedNode != null) {
316        IPluginDescription plugin = typesTreeView.SelectedNode.Tag as IPluginDescription;
317        if (plugin != null) {
318          StringBuilder sb = new StringBuilder();
319          sb.Append("Plugin: ").Append(plugin.Name).Append(Environment.NewLine);
320          sb.Append("Version: ").Append(plugin.Version.ToString()).Append(Environment.NewLine);
321          descriptionTextBox.Text = sb.ToString();
322        }
323        Type type = typesTreeView.SelectedNode.Tag as Type;
324        if (type != null) {
325          string description = ItemAttribute.GetDescription(type);
326          if (description != null)
327            descriptionTextBox.Text = description;
328        }
329      } else if (typesTreeView.Nodes.Count == 0) {
330        descriptionTextBox.Text = "No types found";
331      }
332    }
333
334    #region Events
335    public event EventHandler SelectedTypeChanged;
336    protected virtual void OnSelectedTypeChanged() {
337      if (SelectedTypeChanged != null)
338        SelectedTypeChanged(this, EventArgs.Empty);
339    }
340    #endregion
341
342    #region Control Events
343    protected virtual void searchTextBox_TextChanged(object sender, System.EventArgs e) {
344      Filter(searchTextBox.Text);
345    }
346
347    protected virtual void typesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
348      if (typesTreeView.SelectedNode == null) SelectedType = null;
349      else SelectedType = typesTreeView.SelectedNode.Tag as Type;
350      UpdateTypeParameters();
351      UpdateDescription();
352    }
353    protected virtual void typesTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
354      TreeNode node = (TreeNode)e.Item;
355      Type type = node.Tag as Type;
356      if ((type != null) && (!type.IsInterface) && (!type.IsAbstract) && (!type.HasElementType) && (!type.ContainsGenericParameters)) {
357        object o = Activator.CreateInstance(type);
358        DataObject data = new DataObject();
359        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, o);
360        DoDragDrop(data, DragDropEffects.Copy);
361      }
362    }
363    protected virtual void typesTreeView_VisibleChanged(object sender, EventArgs e) {
364      if (Visible) SetTreeNodeVisibility();
365    }
366
367    protected virtual void typeParametersListView_SelectedIndexChanged(object sender, EventArgs e) {
368      setTypeParameterButton.Enabled = typeParametersListView.SelectedItems.Count == 1;
369    }
370    protected virtual void typeParametersListView_DoubleClick(object sender, EventArgs e) {
371      if (typeParametersListView.SelectedItems.Count == 1)
372        SetTypeParameter();
373    }
374
375    protected virtual void setTypeParameterButton_Click(object sender, EventArgs e) {
376      SetTypeParameter();
377    }
378    private void searchTextBox_KeyDown(object sender, KeyEventArgs e) {
379      if (typesTreeView.Nodes.Count == 0)
380        return;
381
382      if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down) {
383        var selectedNode = typesTreeView.SelectedNode;
384
385        if (selectedNode == null) { // nothing selected => select first
386          if (e.KeyCode == Keys.Down) typesTreeView.SelectedNode = typesTreeView.Nodes.Count > 0 ? typesTreeView.Nodes[0] : null;
387        } else {
388          if (e.KeyCode == Keys.Down && selectedNode.NextVisibleNode != null)
389            typesTreeView.SelectedNode = selectedNode.NextVisibleNode;
390          if (e.KeyCode == Keys.Up && selectedNode.PrevVisibleNode != null)
391            typesTreeView.SelectedNode = selectedNode.PrevVisibleNode;
392        }
393        e.Handled = true;
394      }
395    }
396    private void clearSearchButton_Click(object sender, EventArgs e) {
397      searchTextBox.Text = string.Empty;
398      searchTextBox.Focus();
399    }
400
401    private TreeNode toolStripMenuNode = null;
402    private void typesTreeView_MouseDown(object sender, MouseEventArgs e) {
403      if (e.Button == MouseButtons.Right) {
404        Point coordinates = typesTreeView.PointToClient(Cursor.Position);
405        toolStripMenuNode = typesTreeView.GetNodeAt(coordinates);
406
407        if (toolStripMenuNode != null && coordinates.X >= toolStripMenuNode.Bounds.Left &&
408            coordinates.X <= toolStripMenuNode.Bounds.Right) {
409          typesTreeView.SelectedNode = toolStripMenuNode;
410
411          expandToolStripMenuItem.Enabled =
412            expandToolStripMenuItem.Visible = !toolStripMenuNode.IsExpanded && toolStripMenuNode.Nodes.Count > 0;
413          collapseToolStripMenuItem.Enabled = collapseToolStripMenuItem.Visible = toolStripMenuNode.IsExpanded;
414        } else {
415          expandToolStripMenuItem.Enabled = expandToolStripMenuItem.Visible = false;
416          collapseToolStripMenuItem.Enabled = collapseToolStripMenuItem.Visible = false;
417        }
418        expandAllToolStripMenuItem.Enabled =
419          expandAllToolStripMenuItem.Visible =
420            !typesTreeView.Nodes.OfType<TreeNode>().All(x => TreeNodeIsFullyExpanded(x));
421        collapseAllToolStripMenuItem.Enabled =
422          collapseAllToolStripMenuItem.Visible = typesTreeView.Nodes.OfType<TreeNode>().Any(x => x.IsExpanded);
423        if (contextMenuStrip.Items.Cast<ToolStripMenuItem>().Any(item => item.Enabled))
424          contextMenuStrip.Show(Cursor.Position);
425      }
426    }
427    private bool TreeNodeIsFullyExpanded(TreeNode node) {
428      return (node.Nodes.Count == 0) || (node.IsExpanded && node.Nodes.OfType<TreeNode>().All(x => TreeNodeIsFullyExpanded(x)));
429    }
430    private void expandToolStripMenuItem_Click(object sender, EventArgs e) {
431      typesTreeView.BeginUpdate();
432      if (toolStripMenuNode != null) toolStripMenuNode.ExpandAll();
433      typesTreeView.EndUpdate();
434    }
435    private void expandAllToolStripMenuItem_Click(object sender, EventArgs e) {
436      typesTreeView.BeginUpdate();
437      typesTreeView.ExpandAll();
438      typesTreeView.EndUpdate();
439    }
440    private void collapseToolStripMenuItem_Click(object sender, EventArgs e) {
441      typesTreeView.BeginUpdate();
442      if (toolStripMenuNode != null) toolStripMenuNode.Collapse();
443      typesTreeView.EndUpdate();
444    }
445    private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e) {
446      typesTreeView.BeginUpdate();
447      typesTreeView.CollapseAll();
448      typesTreeView.EndUpdate();
449    }
450    #endregion
451
452    #region Helpers
453    private void RestoreSelectedNode(TreeNode selectedNode) {
454      if (selectedNode != null) {
455        foreach (TreeNode node in typesTreeView.Nodes) {
456          if (node.Text.Equals(selectedNode.Text)) typesTreeView.SelectedNode = node;
457          foreach (TreeNode child in node.Nodes) {
458            if ((child.Text.Equals(selectedNode.Text)) && (child.Tag == selectedNode.Tag))
459              typesTreeView.SelectedNode = child;
460          }
461        }
462        if (typesTreeView.SelectedNode == null) SelectedType = null;
463      }
464    }
465    private void SetTreeNodeVisibility() {
466      TreeNode selectedNode = typesTreeView.SelectedNode;
467      if (string.IsNullOrEmpty(currentSearchString) && (typesTreeView.Nodes.Count > 1)) {
468        typesTreeView.CollapseAll();
469        if (selectedNode != null) typesTreeView.SelectedNode = selectedNode;
470      } else {
471        typesTreeView.ExpandAll();
472      }
473      if (selectedNode != null) selectedNode.EnsureVisible();
474    }
475    #endregion
476  }
477}
Note: See TracBrowser for help on using the repository browser.