Friday, November 19, 2021

Introduction to Interfacing Win Forms with VS Add-ins

 In previous article, we had discussed about VS add-ins. In this article, we will look into interfacing Win Forms to it. Integrating Win Forms in add-ins gives a better UI for interactions. I am going to explain the integration by a sample. Open our VS 2008 and create a new VS add-in as explained in previous article with name as WinFormAddin.

Now add a new Form named as MyForm to the add-in as shown below:

We will make our Form to show list of opened VS windows. Design the form as shown below:

Go to connect.cs and add below code to Exec method:

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)

                   {

                             handled = false;

if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)

                             {

                   if(commandName == "WinFormAddin.Connect.WinFormAddin")

                                      {

                                                handled = true;

MyForm objFrm = new MyForm((DTE2)_applicationObject);

objFrm.Show();

                                                return;

                                      }

                             }

                   }

Here, we are passing DTE2 to our form. By using this DTE2 instance, we can work on Visual Studio IDE events, windows etc. When we run our add-in, it will call Exec(). In this method, we are defining form's instance and passing DTE2 (_applicationobject) to it.

Now, go to code-behind of MyForm and add below code to it:

public partial class MyForm : Form

    {

        public DTE2 MyDTE;

        public List<Window> MyWindows = new List<Window>();

        public Button PrevButton;

        public int FormHeight = 25;

        public MyForm(DTE2 myDTE)

        {

            MyDTE = myDTE;

            InitializeComponent();

        }

 

        private void MyForm_Load(object sender, EventArgs e)

        {

            LoadAllWindows();

        }

 

        private void LoadAllWindows()

        {

            if (MyDTE != null)

            {

                cxtOpenedWindows.Items.Clear();

                MyWindows.Clear();

                this.Controls.Clear();

                //Get List of Opened Windows.

                for (int i = 1; i <= MyDTE.Windows.Count; i++)

                {

cxtOpenedWindows.Items.Add(MyDTE.Windows.Item(i).Caption, nullnew EventHandler(WindowHandler));

                    MyWindows.Add(MyDTE.Windows.Item(i));

                    Button btn = new Button();

                    btn.Text = MyDTE.Windows.Item(i).Caption;

                    btn.Height = 20;

                    btn.Width = this.Width - 10;

                    if (PrevButton == null)

                    {

                        btn.Top = 0;

                    }

                    else

                    {

                        btn.Top = PrevButton.Top + 20;

                    }

                    FormHeight += btn.Height;

                    btn.Click += new EventHandler(btn_Click);

                    PrevButton = btn;

                    this.Controls.Add(btn);

                }

cxtOpenedWindows.Items.Add("Refresh Windows"nullnew EventHandler(WindowHandler));

                this.Height = FormHeight;

            }

        }

        void btn_Click(object sender, EventArgs e)

        {

            string name = ((Button)sender).Text;

            OpenSelectedWin(name);

        }

        private void WindowHandler(object sender, EventArgs e)

        {

            string  name = ((ToolStripItem)sender).Text;

            OpenSelectedWin(name);

        }

 

        private void OpenSelectedWin(string name)

        {

           //To refresh Windows List.

            if (name == "Refresh Windows")

            {

                PrevButton = null;

                FormHeight = 25;

                LoadAllWindows();

                return;

            }

            foreach (Window w in MyWindows)

            {

                if (w.Caption == name)

                {

                    w.Activate();

                    break;

                }

            }

        }

    }

On Form load, we are getting list of opened windows using MyDTE.Windows collection. Than, we are creating a button and contect menu item for each opened window. Finally, on click of the button ; we are calling Activate() to set focus to the selected window. Run the application and select Tools  WinFormAddIn and the output will be as shown below:

When we click on the button, it will set focus to that window. In this way, we can integrate win forms using DTE2 events and methods.

I am ending up the things here. I am attaching source code for reference. I hope this article will be helpful for all.

No comments:

Post a Comment

No String Argument Constructor/Factory Method to Deserialize From String Value

  In this short article, we will cover in-depth the   JsonMappingException: no String-argument constructor/factory method to deserialize fro...