Skip to content

Commit 075e021

Browse files
Exploring using IVsHierarchyItem as basis for new DTE
1 parent af15bab commit 075e021

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/Community.VisualStudio.Toolkit.Shared/Events/SelectionEvents.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,26 @@ internal SelectionEvents()
2323
/// Fires when the selection changes
2424
/// </summary>
2525
public event EventHandler<SelectionChangedEventArgs>? SelectionChanged;
26-
26+
2727
/// <summary>
2828
/// Fires when the UI Context changes.
2929
/// </summary>
30-
public event EventHandler<UIContextChangedEventArgs>? UIContextChanged;
30+
public event EventHandler<UIContextChangedEventArgs>? UIContextChanged;
3131

3232
int IVsSelectionEvents.OnSelectionChanged(IVsHierarchy pHierOld, uint itemidOld, IVsMultiItemSelect pMISOld, ISelectionContainer pSCOld, IVsHierarchy pHierNew, uint itemidNew, IVsMultiItemSelect pMISNew, ISelectionContainer pSCNew)
3333
{
34-
SelectionChanged?.Invoke(this, new SelectionChangedEventArgs(pHierOld, pHierNew));
34+
ThreadHelper.ThrowIfNotOnUIThread();
35+
36+
ThreadHelper.JoinableTaskFactory.RunAsync(async delegate
37+
{
38+
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
39+
40+
IVsHierarchyItem? from = await pHierOld.ToHierarcyItemAsync(itemidOld);
41+
IVsHierarchyItem? to = await pHierNew.ToHierarcyItemAsync(itemidNew);
42+
43+
SelectionChanged?.Invoke(this, new SelectionChangedEventArgs(from, to));
44+
}).FireAndForget();
45+
3546
return VSConstants.S_OK;
3647
}
3748

@@ -55,7 +66,7 @@ public class SelectionChangedEventArgs : EventArgs
5566
/// <summary>
5667
/// Creates a new instance of the EventArgs.
5768
/// </summary>
58-
public SelectionChangedEventArgs(IVsHierarchy from, IVsHierarchy to)
69+
public SelectionChangedEventArgs(IVsHierarchyItem? from, IVsHierarchyItem? to)
5970
{
6071
From = from;
6172
To = to;
@@ -64,11 +75,11 @@ public SelectionChangedEventArgs(IVsHierarchy from, IVsHierarchy to)
6475
/// <summary>
6576
/// What the selection was before the change.
6677
/// </summary>
67-
public IVsHierarchy From { get; }
78+
public IVsHierarchyItem? From { get; }
6879

6980
/// <summary>
7081
/// What the selection is currently after the change.
7182
/// </summary>
72-
public IVsHierarchy To { get; }
83+
public IVsHierarchyItem? To { get; }
7384
}
7485
}

src/Community.VisualStudio.Toolkit.Shared/ExtensionMethods/IVsHierarchyExtensions.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
2+
using System.Threading.Tasks;
3+
using Community.VisualStudio.Toolkit;
24
using EnvDTE;
35
using Microsoft.Internal.VisualStudio.PlatformUI;
6+
using Microsoft.VisualStudio.ComponentModelHost;
47

58
namespace Microsoft.VisualStudio.Shell.Interop
69
{
@@ -30,6 +33,23 @@ public static bool TryGetItemProperty<T>(this IVsHierarchy hierarchy, uint itemI
3033
return true;
3134
}
3235

36+
/// <summary>
37+
/// Converts a <see cref="IVsHierarchy"/> to a <see cref="IVsHierarchyItem"/>.
38+
/// </summary>
39+
/// <returns>Returns <see langword="null"/> if unable to get the hierarchy item.</returns>
40+
public static async Task<IVsHierarchyItem?> ToHierarcyItemAsync(this IVsHierarchy hierarchy, uint itemId)
41+
{
42+
if (hierarchy == null) return null;
43+
44+
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
45+
IComponentModel components = await VS.GetRequiredServiceAsync<SComponentModel, IComponentModel>();
46+
47+
IVsHierarchyItemManager? manager = components.GetService<IVsHierarchyItemManager>();
48+
49+
manager.TryGetHierarchyItem(hierarchy, itemId, out IVsHierarchyItem? item);
50+
return item;
51+
}
52+
3353
/// <summary>
3454
/// Converts an IVsHierarchy to a Project.
3555
/// </summary>
@@ -47,6 +67,23 @@ public static bool TryGetItemProperty<T>(this IVsHierarchy hierarchy, uint itemI
4767
return obj as Project;
4868
}
4969

70+
/// <summary>
71+
/// Converts an IVsHierarchy to a ProjectItem.
72+
/// </summary>
73+
public static ProjectItem? ToProjectItem(this IVsHierarchy hierarchy, uint itemId)
74+
{
75+
ThreadHelper.ThrowIfNotOnUIThread();
76+
77+
if (hierarchy == null)
78+
{
79+
throw new ArgumentNullException(nameof(hierarchy));
80+
}
81+
82+
hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out var obj);
83+
84+
return obj as ProjectItem;
85+
}
86+
5087
/// <summary>
5188
/// Returns whether the specified <see cref="IVsHierarchy"/> is an 'SDK' style project.
5289
/// </summary>

0 commit comments

Comments
 (0)