I want to create a Pad (tool window) in my add-in and show it when the user clicks an item in the menu. How do I do this?

asked 01 Jun '10, 05:56

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦
696262833
accept rate: 50%


Create the ViewModel

  1. By convention, create a Pads directory in your Add-In project.
  2. In the Pads directory, create a new class (assume it's called MyPad for now). When naming this class, I leave out the ViewModel suffix because in SoapBox Core Add-Ins, everything that isn't a View is a ViewModel.
  3. Visual Studio will put it in the YourNameSpace.YourSubNameSpace.AddInName.Pads namespace, but I suggest removing the .Pads from the end.
  4. Add the following using statements: using SoapBox.Core; using System.ComponentModel.Composition;
  5. Make your class inherit from AbstractPad.
  6. Add a constructor, and set the following properties:
    Name = "MyPad"; // needs to be unique within the entire application
    Title = "Some Title Bar Text"; // Better to use Resources.Strings.MyTitleString to support localization
  7. Create a file called CompositionPoints.cs in the root of your project, if you haven't already. Here's what it should look like:

    namespace YourNameSpace.YourSubNameSpace.AddInName.CompositionPoints
    {
        public static class Workbench
        {
            public static class Pads
            {
                public const string MyPad = "CompositionPoints.Workbench.Pads.MyPad";
            }
        }
    }
    
  8. Add the following attributes to your class (the first line lets the Workbench tell the Layout manager about it, and makes sure it gets constructed during composition, the second line is so that other code in your Add-In or other Add-Ins can find your specific pad, and show it, etc., and the third line is so the Layout Manager can find it without instantiating it to find the Name property if it needs to restore it on application startup):
    [Export(SoapBox.Core.ExtensionPoints.Workbench.Pads, typeof(IPad))]
    [Export(CompositionPoints.Workbench.Pads.MyPad, typeof(MyPad))]
    [Pad(Name = "MyPad")] // must match Name property above (hint: use a const)

  9. If you want to execute something when the Pad gets focus, then override this method:
    public override void OnGotFocus(object sender, System.Windows.RoutedEventArgs e)

  10. Now add any properties that you want the View to bind to. For example:

    public string MyProperty
    {
        get { return "My Property Value"; }
    }
    

Create the View

We use a WPF DataTemplate to automatically map a View to this ViewModel:

  1. Add a new Resource Dictionary to the Pads project folder, and give it a name of MyPadView(.xaml).
  2. Edit the ResourceDictionary tag in the Xaml and add these attributes:
    xmlns:local="clr-namespace:YourNamespace.YourSubNamespace.AddInName" x:Class="YourNamespace.YourSubNamespace.AddInName.MyPadView"

  3. Within the ResourceDictionary contents, add a DataTemplate that maps to your ViewModel:

    <DataTemplate DataType="{x:Type local:MyPad}">
        <TextBlock Text="{Binding MyProperty}"/>
    </DataTemplate>
    
  4. Add a new code file to the Layout directory and name it MyPadView.xaml.cs (has to match the name of the Resource Dictionary but with an additional .cs extension).

  5. Copy and paste this into the new code file (this registers this resource dictionary for insertion into the application resources when the application runs):

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Windows;
    
    namespace YourNamespace.YourSubNamespace.AddInName
    {
        [Export(SoapBox.Core.ExtensionPoints.Host.Views, typeof(ResourceDictionary))]
        public partial class MyPadView : ResourceDictionary
        {
            public MyPadView()
            {
                InitializeComponent();
            }
        }
    }
    

Showing the Pad

From somewhere else in your Add-In (like a menu item, tool bar item, or some other window), you can cause this new pad to be shown using the following code:

layoutManager.Value.ShowPad(myPad.Value);

This assumes that layoutManager is a reference to a SoapBox.Core ILayoutManager interface and myPad is a reference to your new Pad. You generally need to use an Import attribute to get these references, like so:

[Import(SoapBox.Core.Services.Layout.LayoutManager, typeof(ILayoutManager))]
private Lazy<ILayoutManager> layoutManager { get; set; }

[Import(CompositionPoints.Workbench.Pads.MyPad, typeof(MyPad))] 
private Lazy<MyPad> myPad { get; set; }

And the class this is declared in needs to export itself as something that some other Add-In or SoapBox.Core will import during startup. Typically this is a menu item, tool bar item, or some similar class.

link

answered 01 Jun '10, 06:07

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦
696262833
accept rate: 50%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×23
×9
×3

Asked: 01 Jun '10, 05:56

Seen: 1,824 times

Last updated: 01 Jun '10, 06:07

powered by OSQA