Skip to content

Commit a750c09

Browse files
committed
ui component : add multiselection to the tree
1 parent a390bf9 commit a750c09

7 files changed

Lines changed: 149 additions & 8 deletions

File tree

sources/RevitDBExplorer/Domain/DataModel/ValueContainers/ElementHandler.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,18 @@ protected override IEnumerable<VisualizationItem> GetVisualization(SnoopableCont
8585
{
8686
yield return new VisualizationItem("Element", "get_BoundingBox(null).Min", new CrossDrawingVisual(bb.Min, VisualizationItem.StartColor));
8787
yield return new VisualizationItem("Element", "get_BoundingBox(null).Max", new CrossDrawingVisual(bb.Max, VisualizationItem.EndColor));
88-
}
88+
}
89+
90+
var view = context.Document.ActiveView;
91+
var geometry = element.get_Geometry(new Options() { View = view});
92+
93+
foreach (var geometryObject in geometry.StreamSolids())
94+
{
95+
if (geometryObject is Solid { Volume: > 0 } solid)
96+
{
97+
yield return new VisualizationItem("Element", "get_Geometry()", new SolidDrawingVisual(solid, VisualizationItem.SolidColor));
98+
}
99+
}
89100
}
90101
}
91102
}

sources/RevitDBExplorer/Extensions/Autodesk.Revit.DB/GeometryObjectExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,26 @@ public static IEnumerable<Curve> StreamCurves(this GeometryObject geometryObject
6666
yield return curve;
6767
}
6868
}
69+
70+
public static IEnumerable<Solid> StreamSolids(this GeometryObject geometryObject)
71+
{
72+
if (geometryObject is GeometryElement geometryElement)
73+
{
74+
foreach (var geometryObject_ in geometryElement)
75+
{
76+
var result = StreamSolids(geometryObject_);
77+
foreach (var item in result) yield return item;
78+
}
79+
}
80+
if (geometryObject is GeometryInstance geometryInstance)
81+
{
82+
var result = StreamSolids(geometryInstance.GetInstanceGeometry());
83+
foreach (var item in result) yield return item;
84+
}
85+
if (geometryObject is Solid solid)
86+
{
87+
yield return solid;
88+
}
89+
}
6990
}
7091
}

sources/RevitDBExplorer/UIComponents/Trees/Base/BaseTreeView.xaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,12 @@
146146
</Style>
147147
<!--<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Yellow"/>-->
148148
</Style.Resources>
149-
<Style.Triggers>
149+
<Style.Triggers>
150+
<DataTrigger Binding="{Binding IsMultiSelected}" Value="True">
151+
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" >
152+
</Setter>
153+
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
154+
</DataTrigger>
150155
<Trigger Property="IsSelected" Value="True">
151156
<Setter Property="BorderBrush" Value="{DynamicResource TreeViewItem.BorderBrush.IsSelected}" />
152157
</Trigger>

sources/RevitDBExplorer/UIComponents/Trees/Base/BaseTreeView.xaml.cs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
using System.Linq;
1+
using System.Collections.Generic;
2+
using System.Linq;
23
using System.Windows;
34
using System.Windows.Controls;
45
using System.Windows.Input;
6+
using System.Windows.Media;
57
using RevitDBExplorer.UIComponents.Trees.Base.Items;
68

79
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
@@ -18,7 +20,7 @@ public BaseTreeView()
1820
{
1921
InitializeComponent();
2022
cTreeView.SelectedItemChanged += TreeView_SelectedItemChanged;
21-
23+
cTreeView.AddHandler(TreeViewItem.MouseLeftButtonDownEvent, new MouseButtonEventHandler(TreeViewItem_MouseLeftButtonDown), true);
2224
}
2325

2426
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
@@ -100,5 +102,54 @@ protected override void OnPreviewMouseMove(MouseEventArgs e)
100102
}
101103
}
102104
}
105+
106+
107+
108+
public void TreeViewItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
109+
{
110+
TreeViewItem treeViewItem = FindTreeViewItem(e.OriginalSource as DependencyObject);
111+
TreeView treeView = sender as TreeView;
112+
TreeItem treeItem = treeViewItem?.DataContext as TreeItem;
113+
114+
if (treeViewItem == null || treeView == null || treeItem == null)
115+
return;
116+
117+
if (this.DataContext is BaseTreeViewModel treeViewVM)
118+
{
119+
if (Keyboard.Modifiers == ModifierKeys.Control)
120+
{
121+
treeViewVM.SelectSingleItem(treeItem, withCtrl: true);
122+
}
123+
else if (Keyboard.Modifiers == ModifierKeys.Shift)
124+
{
125+
//SelectMultipleItemsContinuously(treeView, treeViewItem);
126+
}
127+
else
128+
{
129+
treeViewVM.SelectSingleItem(treeItem, withCtrl: false);
130+
}
131+
}
132+
e.Handled = true;
133+
}
134+
135+
private static TreeViewItem FindTreeViewItem(DependencyObject dependencyObject)
136+
{
137+
if (dependencyObject is System.Windows.Controls.Primitives.ButtonBase)
138+
return null;
139+
140+
if (dependencyObject == null)
141+
{
142+
return null;
143+
}
144+
145+
TreeViewItem treeViewItem = dependencyObject as TreeViewItem;
146+
if (treeViewItem != null)
147+
{
148+
return treeViewItem;
149+
}
150+
151+
return FindTreeViewItem(VisualTreeHelper.GetParent(dependencyObject));
152+
}
153+
103154
}
104155
}

sources/RevitDBExplorer/UIComponents/Trees/Base/BaseTreeViewModel.cs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void RaiseSelectedItemChanged(TreeItem item)
8383
{
8484
var oldOne = SelectedItem;
8585
SelectedItem = item;
86-
SelectedItemChanged?.Invoke(new TreeSelectedItemChangedEventArgs(this, oldOne, item));
86+
SelectedItemChanged?.Invoke(new TreeSelectedItemChangedEventArgs(this, oldOne, item));
8787
}
8888

8989

@@ -99,6 +99,43 @@ public IEnumerable<SnoopableObjectTreeItem> StreamSnoopableObjectTreeItems()
9999
}
100100

101101

102+
// multiselection
103+
private List<TreeItem> selectedItems = new List<TreeItem>();
104+
public void ResetMultiSelection()
105+
{
106+
selectedItems.Clear();
107+
}
108+
public void SelectSingleItem(TreeItem treeItem, bool withCtrl)
109+
{
110+
if (treeItem == null)
111+
return;
112+
113+
if (withCtrl == false)
114+
{
115+
selectedItems.ForEach(x => x.IsMultiSelected = false);
116+
selectedItems.Clear();
117+
treeItem.IsMultiSelected = true;
118+
selectedItems.Add(treeItem);
119+
}
120+
if (withCtrl == true)
121+
{
122+
if (treeItem.IsMultiSelected)
123+
{
124+
treeItem.IsMultiSelected = false;
125+
treeItem.IsSelected = false;
126+
selectedItems.Remove(treeItem);
127+
}
128+
else
129+
{
130+
treeItem.IsMultiSelected = true;
131+
selectedItems.Add(treeItem);
132+
}
133+
}
134+
}
135+
136+
137+
138+
102139
public static IEnumerable<object> GetObjectsForTransfer(TreeItem treeViewItem)
103140
{
104141
return treeViewItem.GetAllSnoopableObjects().Where(x => x.Object != null).Select(x => x.Object).ToArray();

sources/RevitDBExplorer/UIComponents/Trees/Base/Items/TreeItem.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace RevitDBExplorer.UIComponents.Trees.Base.Items
1313
internal abstract class TreeItem : BaseViewModel
1414
{
1515
private bool isSelected = false;
16+
private bool isMultiSelected = false;
1617
private bool isExpanded = false;
1718
private bool isEnabled = true;
1819
private bool isSelectedinRevit = false;
@@ -30,6 +31,18 @@ public bool IsSelected
3031
OnPropertyChanged();
3132
}
3233
}
34+
public bool IsMultiSelected
35+
{
36+
get
37+
{
38+
return isMultiSelected;
39+
}
40+
set
41+
{
42+
isMultiSelected = value;
43+
OnPropertyChanged();
44+
}
45+
}
3346
public bool IsExpanded
3447
{
3548
get
@@ -116,7 +129,7 @@ public void Collapse()
116129
}
117130
}
118131
}
119-
public void SelectFirstDeepestVisibleItem()
132+
public TreeItem SelectFirstDeepestVisibleItem()
120133
{
121134
TreeItem candidate = null;
122135

@@ -127,12 +140,13 @@ public void SelectFirstDeepestVisibleItem()
127140

128141
if (candidate != null)
129142
{
130-
candidate.SelectFirstDeepestVisibleItem();
143+
candidate = candidate.SelectFirstDeepestVisibleItem();
131144
}
132145
else
133146
{
134147
IsSelected = true;
135148
}
149+
return candidate;
136150
}
137151
public IEnumerable<SnoopableObject> GetAllSnoopableObjects()
138152
{

sources/RevitDBExplorer/UIComponents/Trees/Explorer/ExplorerTreeViewModel.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public void ClearItems()
7171
}
7272
public void PopulateTreeView(SourceOfObjects sourceOfObjects)
7373
{
74+
ResetMultiSelection();
7475
EnrichWithVisibilityData = sourceOfObjects?.Info?.EnrichWithVisibilityData == true;
7576
TreeNotForEvents = true;
7677
FilterPhrase = "";
@@ -91,7 +92,8 @@ public void PopulateTreeView(SourceOfObjects sourceOfObjects)
9192
{
9293
groupTreeVM.IsExpanded = true;
9394
}
94-
groupTreeVM.SelectFirstDeepestVisibleItem();
95+
var treeItem = groupTreeVM.SelectFirstDeepestVisibleItem();
96+
SelectSingleItem(treeItem, false);
9597

9698
if (groupTreeVM.Items.Count == 1)
9799
{

0 commit comments

Comments
 (0)