Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please Provide Event Code Samples #33

Open
ghost opened this issue Feb 18, 2022 · 1 comment
Open

Please Provide Event Code Samples #33

ghost opened this issue Feb 18, 2022 · 1 comment

Comments

@ghost
Copy link

ghost commented Feb 18, 2022

@madskristensen; Please provide some code samples for the events used in the ToolKit. I tried to create some from the code in the ToolKit on GitHub, but nothing is working correctly, or the events fire five times per action. Specifically, Editor document opened/created, and Editor document closed/destroyed.

@ghost
Copy link
Author

ghost commented Feb 21, 2022

@madskristensen even thou it would be nice to have code samples for the events. I got it working using IVsRunningDocTableEvents the events still fire three times the file is touched but the code handles this now and does not make unwanted changes. see below:

`using Community.VisualStudio.Toolkit;

using LinqLanguageEditor2022.Extensions;

using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;

using static System.Net.Mime.MediaTypeNames;

namespace LinqLanguageEditor2022.ToolWindows
{
public class LinqToolWindow : BaseToolWindow
{
public override string GetTitle(int toolWindowId) => Constants.LinqEditorToolWindowTitle;

    public override Type PaneType => typeof(Pane);

    public override async Task<FrameworkElement> CreateAsync(int toolWindowId, CancellationToken cancellationToken)
    {
        Project project = await VS.Solutions.GetActiveProjectAsync();
        LinqToolWindowMessenger toolWindowMessenger = await Package.GetServiceAsync<LinqToolWindowMessenger, LinqToolWindowMessenger>();
        return new LinqToolWindowControl(project, toolWindowMessenger);
    }

    [Guid("A938BB26-03F8-4861-B920-6792A7D4F07C")]
    internal class Pane : ToolWindowPane, IVsRunningDocTableEvents
    {

        private uint rdtCookie;
        private EnvDTE.Window win;
        protected override void Initialize()
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            IVsRunningDocumentTable rdt = (IVsRunningDocumentTable)
            this.GetService(typeof(SVsRunningDocumentTable));
            rdt.AdviseRunningDocTableEvents(this, out rdtCookie);
        }

        public Pane()
        {
            BitmapImageMoniker = KnownMonikers.ToolWindow;
            ToolBar = new CommandID(PackageGuids.LinqLanguageEditor2022, PackageIds.LinqTWindowToolbar);
        }
        public int OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            {
                try
                {
                    var activeItem = await VS.Solutions.GetActiveItemAsync();
                    if (activeItem != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnAfterFirstDocumentLock: {activeItem.Name}");
                    }
                }
                catch (Exception)
                {

                }
            }).FireAndForget();
            return VSConstants.S_OK;
        }

        public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            {
                try
                {
                    var activeItem = await VS.Solutions.GetActiveItemAsync();
                    if (activeItem != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnBeforeLastDocumentUnlock: {activeItem.Name}");
                    }
                }
                catch (Exception)
                {

                }
            }).FireAndForget();
            return VSConstants.S_OK;
        }

        public int OnAfterSave(uint docCookie)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            {
                try
                {
                    var activeItem = await VS.Solutions.GetActiveItemAsync();
                    if (activeItem != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnAfterSave: {activeItem.Name}");
                    }
                }
                catch (Exception)
                {

                }
            }).FireAndForget();

            return VSConstants.S_OK;
        }

        public int OnAfterAttributeChange(uint docCookie, uint grfAttribs)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            {
                try
                {
                    var activeItem = await VS.Solutions.GetActiveItemAsync();
                    if (activeItem != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnAfterAttributeChange: {activeItem.Name}");
                    }
                }
                catch (Exception)
                {

                }
            }).FireAndForget();

            return VSConstants.S_OK;
        }

        public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                try
                {
                    var activeItem = await VS.Solutions.GetActiveItemAsync();
                    if (activeItem != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnBeforeDocumentWindowShow: {activeItem.Name}");
                    }
                }
                catch (Exception)
                {

                }
                try
                {
                    win = VsShellUtilities.GetWindowObject(pFrame);
                    if (win != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnBeforeDocumentWindowShow: {win.Caption}");
                    }
                }
                catch (Exception)
                {

                }
                win = VsShellUtilities.GetWindowObject(pFrame);
                string currentFilePath = win.Document.Path;
                string currentFileTitle = win.Document.Name;
                string currentFileFullPath = System.IO.Path.Combine(currentFilePath, currentFileTitle);
                if (pFrame != null && currentFileTitle.EndsWith(".linq"))
                {
                    ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
                    {
                        Project project = await VS.Solutions.GetActiveProjectAsync();
                        if (project != null)
                        {
                            XDocument xdoc = XDocument.Load(project.FullPath);
                            //await project.AddExistingFilesAsync(currentFileFullPath);
                            try
                            {
                                xdoc = RemoveEmptyItemGroupNode(xdoc);
                                xdoc.Save(project.FullPath);
                                await project.SaveAsync();
                                xdoc = XDocument.Load(project.FullPath);
                            }
                            catch (Exception)
                            {

                            }
                            if (ItemGroupExists(xdoc, "ItemGroup", "Compile"))
                            {
                                try
                                {
                                    if (CompileItemExists(xdoc, currentFileTitle))
                                    {
                                        xdoc = UpdateItemGroupItem(xdoc, currentFileTitle, currentFileFullPath);
                                    }
                                    else if (ItemGroupExists(xdoc, "ItemGroup", "None"))
                                    {
                                        try
                                        {
                                            if (NoneCompileItemExists(xdoc, currentFileTitle))
                                            {
                                                xdoc = UpdateItemGroupItem(xdoc, currentFileTitle, currentFileFullPath);
                                            }
                                            else
                                            {
                                                xdoc = CreateNewCompileItem(xdoc, currentFileFullPath);
                                            }
                                            xdoc.Save(project.FullPath);
                                            await project.SaveAsync();
                                            xdoc = XDocument.Load(project.FullPath);
                                        }
                                        catch (Exception)
                                        {

                                        }
                                    }
                                    else
                                    {
                                        xdoc = CreateNewCompileItem(xdoc, currentFileFullPath);
                                    }
                                    xdoc.Save(project.FullPath);
                                    await project.SaveAsync();
                                    xdoc = XDocument.Load(project.FullPath);
                                }
                                catch (Exception)
                                {

                                }
                            }
                            else if (ItemGroupExists(xdoc, "ItemGroup", "None"))
                            {
                                try
                                {
                                    if (NoneCompileItemExists(xdoc, currentFileTitle))
                                    {
                                        xdoc = UpdateItemGroupItem(xdoc, currentFileTitle, currentFileFullPath);
                                    }
                                    else
                                    {
                                        xdoc = CreateNewCompileItem(xdoc, currentFileFullPath);
                                    }
                                    xdoc.Save(project.FullPath);
                                    await project.SaveAsync();
                                    xdoc = XDocument.Load(project.FullPath);
                                }
                                catch (Exception)
                                {

                                }
                            }
                            else
                            {
                                xdoc = CreateNewItemGroup(xdoc, currentFileFullPath);
                                xdoc.Save(project.FullPath);
                                await project.SaveAsync();
                            }
                        }
                    }).FireAndForget();
                }
            }).FireAndForget();
            return VSConstants.S_OK;
        }
        public XDocument RemoveEmptyItemGroupNode(XDocument xdoc)
        {
            try
            {
                xdoc.Descendants("ItemGroup").Where(rec => rec.Nodes().IsNullOrEmpty()).Remove();
                return xdoc;
            }
            catch (Exception)
            {
            }
            return xdoc;
        }

        public bool ItemGroupExists(XDocument xdoc, string groupName, string compile)
        {
            try
            {
                if (!xdoc.Descendants(groupName).Descendants(compile).IsNullOrEmpty())
                {
                    return true;
                }
                return false;
            }
            catch (Exception)
            {
                return false;
            }

        }

        public bool NoneCompileItemExists(XDocument xdoc, string currentFileTitle)
        {
            try
            {
                if (!xdoc.Descendants("ItemGroup").Descendants("None").Where(rec => rec.Attribute("Include").Value.EndsWith(currentFileTitle)).IsNullOrEmpty())
                {
                    return true;
                }
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }
        public bool CompileItemExists(XDocument xdoc, string currentFileTitle)
        {
            try
            {
                if (!xdoc.Descendants("ItemGroup").Descendants("Compile").Where(rec => rec.Attribute("Include").Value.EndsWith(currentFileTitle)).IsNullOrEmpty())
                {
                    return true;
                }
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public XDocument CreateNewCompileItem(XDocument xdoc, string currentFileFullPath)
        {
            var newCompileItem = xdoc.Descendants("ItemGroup").Descendants("Compile").First(x => x.HasAttributes);
            newCompileItem.AddAfterSelf(new XElement("Compile", new XAttribute("Include", currentFileFullPath)));
            return xdoc;
        }
        public XDocument CreateNewItemGroup(XDocument xdoc, string currentFileFullPath)
        {
            XElement itemGroup = new XElement("ItemGroup");
            XElement compile = new XElement("Compile", new XAttribute("Include", currentFileFullPath));
            itemGroup.Add(compile);
            xdoc.Element("Project").Add(itemGroup);
            return xdoc;
        }
        public XDocument UpdateItemGroupItem(XDocument xdoc, string currentFileTitle, string currentFileFullPath)
        {
            if (!NoneCompileItemExists(xdoc, currentFileFullPath))
            {
                currentFileFullPath = currentFileTitle;
            }
            try
            {
                IEnumerable<XElement> xObj = xdoc.Descendants("ItemGroup").Descendants("None").Where(rec => rec.Attribute("Include").Value == currentFileFullPath);

                foreach (var element in xObj)
                {
                    element.Name = "Compile";
                }
                return xdoc;
            }
            catch (Exception)
            {
            }
            return xdoc;
        }
        public XDocument RemoveCompileItem(XDocument xdoc, string caption)
        {
            try
            {
                xdoc.Descendants("ItemGroup").Descendants("Compile").Where(rec =>
                {
                    ThreadHelper.ThrowIfNotOnUIThread();
                    return rec.Attribute("Include").Value.EndsWith(caption);
                }).Remove();
                return xdoc;
            }
            catch (Exception)
            {

            }
            return xdoc;
        }
        public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                try
                {
                    var activeItem = await VS.Solutions.GetActiveItemAsync();
                    if (activeItem != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnAfterDocumentWindowHide: {activeItem.Name}");
                    }
                }
                catch (Exception)
                {

                }
                try
                {
                    var win = VsShellUtilities.GetWindowObject(pFrame);
                    if (win != null)
                    {
                        ((LinqToolWindowControl)this.Content).LinqlistBox.Items.Add($"OnAfterDocumentWindowHide: {win.Caption}");
                    }
                }
                catch (Exception)
                {

                }
                win = VsShellUtilities.GetWindowObject(pFrame);
                if (pFrame != null && win.Caption.EndsWith(".linq"))
                {
                    ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
                    {
                        await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                        Project project = await VS.Solutions.GetActiveProjectAsync();
                        if (project != null)
                        {
                            XDocument xdoc = XDocument.Load(project.FullPath);
                            try
                            {
                                xdoc = RemoveCompileItem(xdoc, win.Caption);
                                xdoc.Save(project.FullPath);
                            }
                            catch (Exception)
                            {
                            }
                            try
                            {
                                xdoc = RemoveEmptyItemGroupNode(xdoc);
                                xdoc.Save(project.FullPath);
                            }
                            catch (Exception)
                            {
                            }
                            xdoc.Save(project.FullPath);
                            await project.SaveAsync();
                        }
                    }).FireAndForget();
                }
            }).FireAndForget();
            return VSConstants.S_OK;
        }
        protected override void Dispose(bool disposing)
        {
            // Release the RDT cookie.
            ThreadHelper.ThrowIfNotOnUIThread();
            IVsRunningDocumentTable rdt = (IVsRunningDocumentTable)
            this.GetService(typeof(SVsRunningDocumentTable));
            rdt.UnadviseRunningDocTableEvents(rdtCookie);

            base.Dispose(disposing);
        }
    }

}

}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants