MultiInstanceItemView makes it possible to have more than one configuration for each item view to the right of the structure tree. It allows for multiple, simultaneous configured ItemViews unlike Item-view which can have only one active instance. 


Prerequisites

The prerequisites are the same as those noted in Getting Started With swExplorer Extensions.


Example Configuration

<ExampleConfigs>
  <ExampleConfig id="1">  
    <ViewSettings> 
      <Caption>One</Caption> 
      <RibbonGroup>My group</RibbonGroup>
    </ViewSettings>
    <TopItemType itemType="I"/>
    <Message>Hello from 1</Message>
  </ExampleConfig>
  <ExampleConfig id="2">
    <Parameters>
      <Parameter name="p1" caption="Parameter:">
        <Values>
          <ForEach select = "/ISSE">
            <AddValue/>
          </ForEach>
        </Values>
      </Parameter>
    </Parameters>
    <ViewSettings>
      <Caption>Two</Caption>
      <RibbonGroup>My group</RibbonGroup>
    </ViewSettings>
    <TopItemType itemType="I"/>
    <Message>Going places</Message>
    <Path>$p1</Path>
  </ExampleConfig>
</ExampleConfigs>


The above configuration would result in a Ribbon group named "My Group" containing two menu icons: one labeled "One" and the other labeled "Two". Both would be using the same extension. 


Explanation of Configuration Elements

<ExampleConfigs> is the top-level element that contains all of the individual configurations. Each configuration should have a unique id (string value).


<ViewSettings> enables you to set a custom view label, hover-tip, icon, etc. See How to Configure Item View Menu Button Settings.

 

<Parameters> offers parameterization, where the user may select which item to include in a view. Drop-downs will automatically be shown in the GUI. The <Values> tag adds values to the parameter, using <AddValue> sub-elements. See Parameters in the application Help for more details. 


<TopItemType> identifies the item type of which the configuration is valid.


Multi Instance Implementation

The implementation of multi-instance extensions is very similar to the ordinary extensions, with some minor differences which will be illustrated in the examples below.

 

Multi Instance Item View

When you create a multi-instance item view, make sure it inherits from IswMultiInstanceItemView, and that the view host is of the type IswMultiInstanceItemViewHost.


using RemObjects.Hydra;
using System;
using SystemWeaver.ExtensionsAPI;
using SystemWeaver.ExtensionsAPI.PluginInterfaces;

namespace SWExtension.Examples
{
    [Plugin, NonVisualPlugin]
    public partial class MultiInstanceItemViewExample : NonVisualPlugin, IswMultiInstanceItemView
    {
        public static IswMultiInstanceItemViewHost ViewHost { get; private set; }
        public static IswBroker Broker { get; private set; }
        public MultiInstanceItemViewExample()
        {
            InitializeComponent();
        }

        public Guid GetGUID()
        {
            return Guid.Parse("798C62B2-04E8-4C46-8799-69A344E4A39A");
        }

        public string GetName()
        {
            return typeof(MultiInstanceItemViewExample).FullName;
        }

        public string GetCaption()
        {
            return "### My multi-instance view";
        }


Get the config, example XML, and tag names from the configuration:

        public string GetPluginContentName()
        {
            return typeof(MultiInstanceItemViewExampleContent).FullName;
        }

        public void Init(IswMultiInstanceItemViewHost host)
        {
            ViewHost = host;
            Broker = ViewHost.GetBroker();
        }

        public string GetConfigXMLExample()
        {
            return MultiInstanceItemViewExampleViewConfig.ExampleXmlConfiguration;
        }

        public string GetDocumentElementTagName()
        {
            return MultiInstanceItemViewExampleViewConfig.DocumentElementTagName;
        }

        public string GetConfigElementTagName()
        {
            return MultiInstanceItemViewExampleViewConfig.ConfigElementTagName;
        }

        public IswViewConfig ParseAndGetConfig(string xml)
        {
            return new MultiInstanceItemViewExampleViewConfig(Broker, xml);
        }
        public bool SupportsItem(IswItem item, IswViewConfig viewConfig)
        {
            return item.IsSID("I");
        }
    }
}


Multi Instance Configuration

The configuration could preferably look something like this: 

namespace SWExtension.Examples
{
    public class MultiInstanceItemViewExampleViewConfig : IswViewConfig
    {
        public static readonly string DocumentElementTagName = "ExampleConfigs";

        public static readonly string ConfigElementTagName = "ExampleConfig";

        public static readonly string ExampleXmlConfiguration =
@"<ExampleConfigs>
  <ExampleConfig id=""1"">  
    <ViewSettings> 
      <Caption>One</Caption> 
      <RibbonGroup>My group</RibbonGroup>
    </ViewSettings>
    <TopItemType itemType=""I""/>
    <Message>Hello from 1</Message>
  </ExampleConfig>
  <ExampleConfig id=""2"">
    <Parameters>
      <Parameter name=""p1"" caption=""Parameter:"">
      <Values>
        <ForEach select = ""/ISSE"">
          <AddValue/>
        </ForEach>
      </Values>
      </Parameter>
    </Parameters>
    <ViewSettings>
      <Caption>Two</Caption>
      <RibbonGroup>My group</RibbonGroup>
    </ViewSettings>
    <TopItemType itemType=""I""/>
    <Message>Going places</Message>
    <Path>$p1</Path>
  </ExampleConfig>
</ExampleConfigs>";


Multi Instance View Content

The multi instance item view content must inherit from MultiInstanceItemViewContent, use the MultiInstanceItemViewWrapper, and the IswMultiInstanceItemViewContentHost.

    [Plugin, VisualPlugin, NeedsManagedWrapper(typeof(MultiInstanceItemViewWrapper))]
    public partial class MultiInstanceItemViewExampleContent : RemObjects.Hydra.WPF.VisualPlugin, IswMultiInstanceItemViewContent
    {
        private IswMultiInstanceItemViewContentHost _host;
        private MultiInstanceItemViewExampleViewConfig _config;
        private IswServerEvent _events;

        public MultiInstanceItemViewExampleContent()
        {
            InitializeComponent();
        }

        public void SetHost(IswMultiInstanceItemViewContentHost host)
        {
            _host = host;
            textServerUrl.Text = MultiInstanceItemViewExample.ViewHost.GetServerUrl();
        }

        public void SetConfig(IswViewConfig config)
        {
            _config = config as MultiInstanceItemViewExampleViewConfig;
            textBlockConfig.Text = _config.Message;
        }

        public void SetCurrentItem(IswItem item)
        {
            if (item == null)
            {
                textBlockCurrentItem.Text = "";
                textBlockPathResult.Text = "";
                return;
            }

            textBlockCurrentItem.Text = $"Current item is {item.Name}";

            IswItems items = (_host as IswHydraStructureTreeGetSubItems).GetSubItems();

            try
            {
                if (string.IsNullOrEmpty(_config.PathExpression))
                {
                    textBlockPathResult.Text = "";
                }
                else
                {
                    IswObjects pathResult = _host.ExecutePathWithParameters(_config.PathExpression, item);
                    textBlockPathResult.Text = string.Join(", ", pathResult.ToArray().Select(x => x.Name));
                }
            }
            catch (COMException e)
            {
                textBlockPathResult.Text = e.Message;
            }
        }

        private void ButtonOpen_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var handle = SWHandleUtility.ToHandle(textItemId.Text);

            IswItem item = MultiInstanceItemViewExample.Broker.GetItem(handle);

            _host.OpenItem(item, THowToOpenType.ChangeFocusOnly);

        }

        private void ButtonIndicate_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var handle = SWHandleUtility.ToHandle(textItemId.Text);

            var item = MultiInstanceItemViewExample.Broker.GetItem(handle);

            var list = MultiInstanceItemViewExample.Broker.Lists.NewItemList();

            list.Add(item);

            _host.IndicateItems(list);
        }

        private void ButtonSelectUser_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            MultiInstanceItemViewExample.ViewHost.GetDialogs().SelectUser(out IswUser user);
        }

        private void ButtonCopyToClipboard_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var handle = SWHandleUtility.ToHandle(textItemId.Text);

            var item = MultiInstanceItemViewExample.Broker.GetItem(handle);

            var list = MultiInstanceItemViewExample.Broker.Lists.NewItemList();

            list.Add(item);

            MultiInstanceItemViewExample.ViewHost.GetClipboard().SetObjects(list);
        }

        private void ButtonConnectClipboard_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            _events = new ExtensionEvents();

            _host.SetEvent(_events);

            IswEvents ev = _events as IswEvents;

            ev.Object_SetName += DoSetName;
        }

        private void DoSetName(IswObject obj)
        {
            textEventInfo.Text = $"Name set to {obj.Name}";
        }
    }
}
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using SystemWeaver.ExtensionsAPI;
using SystemWeaver.ExtensionsAPI.PluginInterfaces;

namespace SWExtension.Examples
{
    public class MultiInstanceItemViewExampleViewConfig : IswViewConfig
    {
        public static readonly string DocumentElementTagName = "ExampleConfigs";

        public static readonly string ConfigElementTagName = "ExampleConfig";

        public static readonly string ExampleXmlConfiguration =
@"<ExampleConfigs>
  <ExampleConfig id=""1"">  
    <ViewSettings> 
      <Caption>One</Caption> 
      <RibbonGroup>My group</RibbonGroup>
    </ViewSettings>
    <TopItemType itemType=""I""/>
    <Message>Hello from 1</Message>
  </ExampleConfig>
  <ExampleConfig id=""2"">
    <Parameters>
      <Parameter name=""p1"" caption=""Parameter:"">
      <Values>
        <ForEach select = ""/ISSE"">
          <AddValue/>
        </ForEach>
      </Values>
      </Parameter>
    </Parameters>
    <ViewSettings>
      <Caption>Two</Caption>
      <RibbonGroup>My group</RibbonGroup>
    </ViewSettings>
    <TopItemType itemType=""I""/>
    <Message>Going places</Message>
    <Path>$p1</Path>
  </ExampleConfig>
</ExampleConfigs>";