Skip to main content

Built-in custom UI

Preview released

This function and the API used in this function have been released in advance. We do not guarantee the quality at this time, so please use it at your own risk. Also, please note that these specifications are subject to change without notice.

Overview

In addition to the UI that comes standard with Next Design, you can extend your model editing capabilities by incorporating your own UI into the following parts:

  • Model editor view
  • Navigator
  • Inspector

Learn how to incorporate a custom UI into Next Design. If you include a custom UI, you don't need to define extension points in the manifest. Instead, you need to add some processing when implementing IExtension in your main class. You can view and edit Next Design models in your custom UI by combining the ViewModel class in your custom UI with the Next Design API.

Incorporating a custom UI requires the following implementation and steps:

  • Implementation of custom UI interface
  • Implementation of custom UI registration process and deregistration process
  • Add custom UI view
tip

The custom UI must follow the architecture of the MVVM model (Model-View-ViewModel).

Implementation of custom UI interface

In the ViewModel class, implement the interface depending on the type of UI.

  • UI type and interface to implement

    UI typeInterface to be implemented in ViewModelProperties/methods that need to be implemented
    Custom EditorICustomEditorViewDescriptor Property
    OnInitialized Method
    OnBeforeDispose Method
    ViewDefinitionId Property
    SelectedItem property
    SelectedItems property
    SetModel method
    GetDocumentContent method (*)
    Custom NavigatorICustomNavigatorDescriptor Property
    OnInitialized Method
    OnBeforeDispose Method
    SelectedItem Property
    SelectedItems property
    IsEnabled method
    OnShow method
    OnHide method
    Custom InspectorICustomInspectorDescriptor Property
    OnInitialized Method
    OnBeforeDispose Method
    SetModel Method

By implementing the above interface, you can connect the Next Design model with the ViewModel class. Please refer to each API specification for details.

note

(*) The GetDocumentContent method is an API prepared for future enhancements. In the current version, it should only return null.

Implementation of custom UI registration process and deregistration process

Implement the custom UI registration process in the public method Activate of the main class that implements IExtention. Then, implement the custom UI deregistration process in the public method Deactviate of the main class.

Activate method: Register custom UI Deactivate method: Deregister custom UI

Implementation example

Here is an example of implementing the IExtension interface in the CustomUISampleEntryPoint class. The implementation of View is the SampleCustomEditor class, and the implementation of ViewModel is the SampleCustomEditorViewModel class.

Implementation example of IExtension

    public class CustomUISampleEntryPoint: IExtension
{
///<summary>
///Processing when extension is activated
///</summary>
///<param name = "context"> </param>
public void Activate (IContext context)
{
var registry = context.App.CustomUI;
var extensionName = context.ExtensionInfo.Name;

//Register the implemented ViewModel and View
//Call the method according to the type of UI implemented
registry.RegisterCustomEditor <SampleCustomEditorViewModel, SampleCustomEditor> (extensionName, SampleCustomEditorViewModel.Descriptor);
}

///<summary>
///Processing when extension is deactivated
///</summary>
///<param name = "context"> </param>
public void Deactivate (IContext context)
{
var registry = context.App.CustomUI;
var extensionName = context.ExtensionInfo.Name;

//Unregister custom UI
registry.UnRegisterAllCustomUIs (extensionName);
}
}

Add custom UI view

If the custom UI type you want to include is an editor, add the custom UI to the view of the target model.

  1. In the Model Navigator, select the target model for your custom UI.
  2. Execute [Add View] from the context menu.
  3. Select the editor name for the custom UI you have included and add a view.
  4. Switch to the added view to view and edit the target model in the built-in custom UI.

Sample: Add Custom Editor/Inspector/Navigator

As an example of a custom UI, add a custom editor/inspector/navigator that looks different from the UI that comes standard with Next Design. The following describes everything from creating a new Visual Studio project to actually embedding a custom UI.

Overall flow

  • Create a new Visual Studio project
  • Add View class and ViewModel class
  • Implementation of custom UI interface in ViewModel class
  • Implementation of custom UI registration process and deregistration process
  • Implementing the UI in the View class
  • Add custom editor view

Public sample

  • A set of sample source code created by the following procedure is available on GitHub.

    External link: CustomUISample

Goal image

Screen capture or GIF animation

  • A custom navigator has been added to the navigator, allowing you to select a model in your own UI.
  • A custom editor has been added to the view types, allowing you to switch the model editor view to the custom editor to view and edit the model in your own UI.
  • A custom inspector has been added to the Inspector tab, allowing you to view and edit detailed information about the model you are editing in your own UI.

Create a new Visual Studio project

When developing a custom UI, select WPF Class Library as the project type when creating a new project. This allows you to place user controls.

The following settings when creating a new project are the same as Tutorials> Batch Model Verification.

  • A copy of the extension development DLL
  • Added reference setting for extension development DLL
  • Automation of debug execution preparation

Create and define a new manifest. The following is similar to Tutorials> Bulk Model Validation.

  • Execution program entry point definition
  • Extension life cycle definition
  • Specify the target profile of the extension

The implementation of a custom UI does not require the following definition in the manifest:

  • UI extension point definition (ribbon tab group button)
  • Command extension point definition

Implementation code

manifest.json

{
//Extension definition
"name": "DensoCreate.NextDesign.Extensions.CustomUISample",
"version": "1.0.0",
"publisher": "DENSO CREATE Inc.",
"license": "Conforms to the Next Design License Agreement. Copyright (C) 2021 DENSO CREATE INC. All rights reserved.",

"main": "CustomUISample.dll", //Specify the DLL file name of the build result as an entry point.
"lifecycle": "application", //Specify the application lifecycle as the lifecycle.
"baseProfile": "" //Do not specify the profile name condition.
}

Add View class and ViewModel class

Add the View and ViewModel classes required for your custom editor, custom navigator, and custom inspector to your Visual Studio project. The class names to be added this time are as follows.

UI type to addView classViewModel class
Custom EditorCustomEditorCustomEditorViewModel
Custom NavigatorCustomNavigatorCustomNavigatorViewModel, CustomNavigatorItemViewModel (*)
CustomInspectorCustomInspectorCustomInspectorViewModel

(*) CustomNavigatorItemViewModel is a class of display elements to be displayed in the custom navigator.

View class

In Visual Studio Solution Explorer, select User Control (WPF) as the new item for your project.

ViewModel class

In Visual Studio Solution Explorer, add the class as a new item to your project.

The configuration of the Visual Studio project with the above added is as follows.

CustomUISample /
CustomUISample.sln
CustomUISample /
CustomUISample.csproj
manifest.json
View /
Editor /
CustomEditor.xaml
CustomEditor.xaml.cs
Inspector /
CustomInspector.xaml
CustomInspector.xaml.cs
Navigator Navigator
CustomNavigator.xaml
CustomNavigator.xaml.cs
ViewModel /
Editor /
CustomEditorViewModel.cs
Inspector /
CustomInspectorViewModel.cs
Navigator Navigator
CustomNavigatorViewModel.cs
CustomUISampleEntryPoint.cs (*)
  • CustomUISampleEntryPoint is the main class that implements the interface of IExtension.

Implementing a custom UI interface in the ViewModel class

In the ViewModel class, implement the following interfaces, depending on the type of UI.

UI type to addInterface to be implemented in ViewModelProperties/methods that need to be implemented
Custom EditorICustomEditorViewViewDefinitionId Property
SelectedItem Property
SelectedItems Property
SetModel Method
GetDocumentContent Method
Custom NavigatorICustomNavigatorSelectedItem Property
SelectedItems Property
IsEnabled Method
OnShow Method
OnHide Method
Custom InspectorICustomInspectorSetModel Method

Implementation code

Custom editor

Implement ICustomEditorView in your custom editor's ViewModel class.

CustomEditorViewModel.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using NextDesign.Core;
using NextDesign.Desktop;
using NextDesign.Desktop.CustomUI;
using NextDesign.Extension;

namespace CustomUISample.ViewModel.Editor
{
class CustomEditorViewModel: ICustomEditorViewModel
{
#region type descriptor

///<summary>
///Type descriptor
///</summary>
private static CustomEditorDefinitionDescriptor s_DefinitionDescriptor;

///<summary>
///Type descriptor
///</summary>
public static CustomEditorDefinitionDescriptor DefinitionDescriptor
{
get get
{
return s_DefinitionDescriptor ?? (s_DefinitionDescriptor = new CustomEditorDefinitionDescriptor
{
//Custom editor type identifier
CustomEditorTypeId = "CustomUI.Test",
//access key
AccessKey = "P",
//display name
DisplayName = "Custom Editor",
//group name
GroupName = "Custom Editor",
//Icon (Large) pack --You can specify a string in uri format or Stream type.
LargeIcon =
"pack: //application: ,,,/CustomUISample; component/Resources/Images/TestEditor32.png",
//Icon (small) pack --You can specify a string in uri format or Stream type.
SmallIcon =
"pack://application: ,,,/CustomUISample; component/Resources/Images/TestEditor16.png"
});
}
}

#endregion

#region property

///<summary>
///Type descriptor
///</summary>
public ICustomDescriptor Descriptor {get; set;}

///<summary>
///Id of the corresponding view definition
///</summary>
public string ViewDefinitionId => Editor? .EditorDefinition.Id;

///<summary>
///Element selected in the editor
///If there is no selected element, implement it to return null.
///</summary>
public object SelectedItem => null;

///<summary>
///List of elements selected in the editor
///If there is no selected element, implement it to return an empty enumeration.
///</summary>
public IEnumerable <object> SelectedItems => Enumerable.Empty <object> ();

///<summary>
///application
///</summary>
public IApplication App {get; private set;}

///<summary>
///Extension
///</summary>
public CustomUISampleEntryPoint Extension {get; private set;}

///<summary>
///Editor information
///</summary>
public ICustomEditor Editor {get; private set;}

///<summary>
///Object model
///</summary>
public IModel TargetModel {get; private set;}

#endregion

#region event handler

///<summary>
///Processing when initializing the user interface to be extended independently
///Next Design calls this method when initializing the user interface that it extends.
///If there is a process you want to execute at initialization on the extension side, implement it here.
///</summary>
///<param name = "args"> </param>
public void OnInitialized (InitializedEventArgs args)
{
//Memorize application and extension information
App = args.App;
Extension = args.Extension as CustomUISampleEntryPoint;
}


///<summary>
///Processing before destroying the user interface that is originally extended
///Next Design calls this method before destroying the user interface that it extends.
///If there is a process you want to execute before discarding on the extension side, implement it here.
///</summary>
///<param name = "args"> </param>
public void OnBeforeDispose (BeforeDisposeEventArgs args)
{
//No processing before discarding
}


#endregion

#region interface implementation

///<summary>
///Set the model to be displayed in this editor.
///</summary>
///<param name = "model"> </param>
public void SetModel (ICustomEditor model)
{
Editor = model;
TargetModel = model.Model;
}

///<summary>
///Get the content of the document output.
///</summary>
///<param name = "context"> </param>
public ICustomEditorDocumentContent GetDocumentContent (ICustomEditorDocumentGenerationContext context)
{
//In the current version, it is fixed to null
return null;
}

#endregion
}
}
Custom Inspector
Implement ICustomInspector in the ViewModel class of the Custom Inspector.

CustomInspectorViewModel.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using NextDesign.Core;
using NextDesign.Desktop.CustomUI;

namespace CustomUISample.ViewModel.Inspector
{
class CustomInspectorViewModel: ICustomInspector
{
#region field

///<summary>
///Target model
///</summary>
private object m_Object;

#endregion

#region property

///<summary>
///Type descriptor
///</summary>
public ICustomDescriptor Descriptor {get; set;}

///<summary>
///name
///</summary>
public string Name
{
get get
{
if (m_Object is IModel model)
{
return $ "{model.Name} ({model.GetType (). Name})";
}
return m_Object? .GetType (). Name;
}
}

#endregion

#region event handler

///<summary>
///Initialize
///</summary>
///<param name = "args"> Event parameters </param>
public void OnInitialized (InitializedEventArgs args)
{
//Processing when initializing the user interface to be extended independently
//Next Design calls this method when initializing the user interface that it extends.
//If there is a process you want to execute at initialization on the extension side, implement it here.
}

///<summary>
///destruction
///</summary>
///<param name = "args"> Event parameters </param>
public void OnBeforeDispose (BeforeDisposeEventArgs args)
{
//Processing before destroying the user interface to be extended independently
//Next Design calls this method before destroying the user interface that it extends.
//If there is a process you want to execute before discarding on the extension side, implement it here.
}

///<summary>
///Set the model to be displayed in this inspector.
///</summary>
///<param name = "target"> target model </param>
///<param name = "targets"> Target models </param>
public void SetModel (object target, IEnumerable <object> targets)
{
m_Object = target;
}

#endregion
}
}

Custom Navigator

Implement ICustomNavigator in the Custom Navigator's ViewModel class.

CustomNavigatorViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Linq;
using NextDesign.Core;
using NextDesign.Desktop;
using NextDesign.Desktop.CustomUI;

namespace CustomUISample.ViewModel.Navigator
{
public class CustomNavigatorViewModel: ICustomNavigator, IDisposable
{
#region property
///<summary>
///Type descriptor
///</summary>
public ICustomDescriptor Descriptor {get; set;}

///<summary>
///Selected item
///</summary>
private object m_SelectedItem;

///<summary>
///Selected item
///</summary>
public object SelectedItem
{
get => m_SelectedItem;
set
{
m_SelectedItem = value;

//If the selected item is Model
//Set the current model of the current workspace and the elements to be inspected.
if (m_SelectedItem is IModel model)
{
Workspace.State.SetCurrentModel (model) ;;
Workspace.State.SetInspectedObject (model) ;;
}
}
}

///<summary>
///List of elements selected in the editor
///If there is no selected element, implement it to return an empty enumeration.
///</summary>
public IEnumerable <object> SelectedItems => Enumerable.Empty <object> ();

///<summary>
///ID
///</summary>

///<summary>
///Item
///</summary>
private ObservableCollection <CustomNavigatorItemViewModel> m_Items;

///<summary>
///Item
///</summary>
public IEnumerable <CustomNavigatorItemViewModel> Items => m_Items;

///<summary>
///Workspace
///</summary>
private IWorkspace Workspace => m_App.Workspace;

#endregion

#region internal field

///<summary>
///configuration
///</summary>
private CustomNavigatorConfigs m_Configs;

///<summary>
///application
///</summary>
private NextDesign.Desktop.IApplication m_App;

#endregion

#region construction/disappearance

///<summary>
///destruction
///</summary>
public void Dispose ()
{
DisposeItems ();
if (m_App! = null)
{
m_App = null;
}
}

///<summary>
///Dispose the item
///</summary>
public void DisposeItems ()
{
if (m_Items == null)
{
return;
}

foreach (var item in m_Items)
{
item.Dispose ();
}

m_Items.Clear ();
m_Items = null;
}

#endregion

#region event handler

///<summary>
///OnInitialized "Process when initializing the user interface to be extended independently
///Next Design calls this method when initializing the user interface that it extends.
///If there is a process you want to execute at initialization on the extension side, implement it here. "
///</summary>
///<param name = "args"> </param>
public void OnInitialized (InitializedEventArgs args)
{
m_Configs = new CustomNavigatorConfigs ();
m_Configs.SelectionMode = SelectionMode.Multiple;
}

///<summary>
///Processing before destroying the user interface that is originally extended
///Next Design calls this method before destroying the user interface that it extends.
///If there is a process you want to execute before discarding on the extension side, implement it here.
///</summary>
///<param name = "args"> </param>
public void OnBeforeDispose (BeforeDisposeEventArgs args)
{
//No processing
}

///<summary>
///Processing when displaying this navigator
///Next Design calls this method when displaying a navigator that extends independently.
///If there is a process you want to execute at the time of display on the extension side, implement it here.
///</summary>
///<param name = "args"> </param>
public void OnShow (OnShowEventArgs args)
{
m_App = args.App;
var project = m_App.Workspace.CurrentProject;
CreateChildren (project);
}

///<summary>
///What to do when hiding this navigator
///Next Design calls this method to hide the navigator that it extends independently.
///If there is a process you want to execute when hidden on the extension side, implement it here.
///</summary>
///<param name = "args"> </param>
public void OnHide (OnHideEventArgs args)
{
//No processing
}

#endregion

#region internal processing

///<summary>
///Generate child elements
///</summary>
///<param name = "project"> </param>
private void CreateChildren (IProject project)
{
if (project == null)
{
return;
}

//Get the child element of the model and generate the child element of the navigator
var models = project.GetChildren (). OfType <IModel> ();
var items = new ObservableCollection <CustomNavigatorItemViewModel> ();
foreach (var model in models)
{
var item = new CustomNavigatorItemViewModel (model, this);
items.Add (item);
}

m_Items = items;
}

///<summary>
///Get the icon
///</summary>
///<param name = "model"> </param>
///<returns> </returns>
internal object GetIcon (IModel model)
{
if (m_App == null)
{
return null;
}

if (model == null)
{
return null;
}

var icon = m_App.Resources.GetObjectIcon (model);
return icon;
}

#endregion
}
}

Implements a class of display elements to display in the custom navigator.

CustomNavigatorItemViewModel.cs**

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Linq;
using NextDesign.Core;

namespace CustomUISample.ViewModel.Navigator
{
///<summary>
///Sample navigator item VM
///</summary>
public class CustomNavigatorItemViewModel: IDisposable
{
#region internal field

///<summary>
///Child element
///</summary>
private ObservableCollection <CustomNavigatorItemViewModel> m_Children;

///<summary>
///model
///</summary>
private IModel m_Model;

///<summary>
///Owner
///</summary>
private CustomNavigatorViewModel m_Owner;

#endregion

#region property

///<summary>
///model
///</summary>
public IModel Model => m_Model;

///<summary>
///Child element
///</summary>
public IEnumerable <CustomNavigatorItemViewModel> Children => m_Children;

///<summary>
///Icon
///</summary>
public object Icon => m_Owner? .GetIcon (Model);

#endregion

#region construction/disappearance

///<summary>
///Constructor
///</summary>
public CustomNavigatorItemViewModel (IModel model, CustomNavigatorViewModel owner)
{
m_Model = model;
m_Owner = owner;

CreateChildren ();
}

///<summary>
///destruction
///</summary>
public void Dispose ()
{
if (m_Model! = null)
{
m_Model = null;
}

if (m_Children! = null)
{
foreach (var child in m_Children)
{
child.Dispose ();
}

m_Children.Clear ();
m_Children = null;
}
}

#endregion

#region internal processing

///<summary>
///Generate child elements
///</summary>
private void CreateChildren ()
{
var children = m_Model.GetChildren (). OfType <IModel> ();
if (! children.Any ())
{
return;
}

if (m_Children == null)
{
m_Children = new ObservableCollection <CustomNavigatorItemViewModel> ();
}

foreach (var child in children)
{
var item = new CustomNavigatorItemViewModel (child, m_Owner);
m_Children.Add (item);
}
}

#endregion
}
}

Implementation of custom UI registration process and deregistration process

Implement the custom UI registration process in the public method Activate of the main class that implements IExtention. Then, implement the custom UI deregistration process in the public method Deactviate of the main class.

Display position of custom inspector and custom navigator

In the custom inspector and custom navigator, the display position is specified by a double type value when registering the custom UI. Next Design The standard inspector and navigator are assigned IDs and unique values. The smaller the value, the more it will be displayed on the left side of the screen, so if you want to display it to the right of a specific inspector or navigator, specify the value of that inspector or navigator +1. The following shows the display position values of the Next Design standard inspector and navigator.

  • Reference: Display position of standard inspector

    InspectorIDValue
    Properties (model)CustomInspectorDescriptor.DisplayOrderModel100
    Related (model)CustomInspectorDescriptor.DisplayOrderRelationship200
    Diagram DefinitionCustomInspectorDescriptor.DisplayOrderDiagramDefinition1000
    Shape Definition (Node)CustomInspectorDescriptor.DisplayOrderNodeShapeDefinition1100
    Shape Definition (Port)CustomInspectorDescriptor.DisplayOrderPortShapeDefinition1200
    Shape Definition (Connector)CustomInspectorDescriptor.DisplayOrderConnectorShapeDefinition1300
    Form DefinitionCustomInspectorDescriptor.CustomInspectorDescriptor2000
    Form element (control)CustomInspectorDescriptor.DisplayOrderFormControlDefinition2100
    Form element (group)CustomInspectorDescriptor.DisplayOrderGroupDefinition2200
    Form element (grid)CustomInspectorDescriptor.DisplayOrderGridDefinition2300
    Form element (list)CustomInspectorDescriptor.DisplayOrderListDefinition2400
    Row DefinitionCustomInspectorDescriptor.DisplayOrderTreeGridRow3100
    Shape Definition (Lifeline)CustomInspectorDescriptor.DisplayOrderLifelineShapeDefinition4100
    Shape Definition (Note (Sequence)/Composite Fragment)CustomInspectorDescriptor.DisplayOrderSequenceNodeShapeDefinition4200
    Shape Definition (Message (Sequence))CustomInspectorDescriptor.DisplayOrderMessageShapeDefinition4300
    Shape Definition (Note Anchor)CustomInspectorDescriptor.DisplayOrderNoteAnchorShapeDefinition4400
    Shape definition (execution specification/discard/message end)CustomInspectorDescriptor.DisplayOrderSequenceShapeDefinition4500
    PackageCustomInspectorDescriptor.DisplayOrderPackage10000
    Metamodel (Class)CustomInspectorDescriptor.DisplayOrderClass11000
    Metamodel (related class)CustomInspectorDescriptor.DisplayOrderRelationshipClass11100
    FileldsCustomInspectorDescriptor.DisplayOrderField12000
    EnumCustomInspectorDescriptor.DisplayOrderEnum13000
  • Reference: Display position of standard navigator

    NavigatorIDValue
    Model NavigatorCustomNavigatorDescriptor.DisplayOrderModel100
    Product line navigatorCustomNavigatorDescriptor.DisplayOrderProductLine200
    SCM NavigatorCustomNavigatorDescriptor.DisplayOrderScm300
    Project NavigatorCustomNavigatorDescriptor.DisplayOrderProject400
    Profile NavigatorCustomNavigatorDescriptor.DisplayOrderProfile500

Type descriptor

When you register your custom UI, you specify the type descriptor. The type descriptor defines static information for the custom UI.

Custom UIType descriptorInformation to define
Custom EditorCustomEditorDescriptorID
CustomEditorDefinitionDescriptor (*)
Custom NavigatorCustomNavigatorDescriptorID
Display name
Display position
Icon
CustomInspectorCustomInspectorDescriptorID
Display name
Display position
  • CustomEditorDefinitionDescriptor defines the following information.

  • ID

  • access key

  • display name

  • group name

  • Icon

Implementation code

Implement custom editor, inspector, navigator registration process and deregistration process.

CustomUISampleEntryPoint.cs

using System;
using CustomUISample.View.Editor;
using CustomUISample.View.Inspector;
using CustomUISample.View.Navigator;
using CustomUISample.ViewModel.Editor;
using CustomUISample.ViewModel.Inspector;
using CustomUISample.ViewModel.Navigator;
using NextDesign.Extension;
using NextDesign.Desktop;
using NextDesign.Desktop.CustomUI;

namespace CustomUISample
{
public class CustomUISampleEntryPoint: IExtension
{
///<summary>
///Processing when extension is activated
///</summary>
///<param name = "context"> </param>
public void Activate (IContext context)
{
var registry = context.App.CustomUI;
var extensionName = context.ExtensionInfo.Name;

//Register custom editor
var customEditorDescriptor = new CustomEditorDescriptor (
typeof (CustomEditorViewModel) .FullName,
CustomEditorViewModel.DefinitionDescriptor
);
registry.RegisterCustomEditor <CustomEditorViewModel, CustomEditor> (extensionName, customEditorDescriptor);

//Register custom inspector
var customInspectorDescriptor = new CustomInspectorDescriptor (
typeof (CustomInspector).FullName,
"Custom Inspector",
(CustomInspectorDescriptor.DisplayOrderNodeShapeDefinition + 1)
);
registry.RegisterCustomInspector <CustomInspectorViewModel, CustomInspector> (extensionName, customInspectorDescriptor);

//Register a custom navigator
//Display between the model navigator and the product line
var customNavigatorDescriptor = new CustomNavigatorDescriptor (
typeof (CustomNavigator) .FullName,
"Custom Navigator",
(CustomNavigatorDescriptor.DisplayOrderModel + 1),
@"pack://application: ,,,/NextDesign; component/Resources/Images/ModelNavigator.png"
);
registry.RegisterCustomNavigator <CustomNavigatorViewModel, CustomNavigator> (extensionName, customNavigatorDescriptor);
}

///<summary>
///Processing when extension is deactivated
///</summary>
///<param name = "context"> </param>
public void Deactivate (IContext context)
{
var registry = context.App.CustomUI;
var extensionName = context.ExtensionInfo.Name;

//Unregister custom UI
registry.UnRegisterAllCustomUIs (extensionName);
}
}
}

Implementation of UI in View class

Place the control in the View class.

Custom editor

Defines a custom editor view.

CustomEditor.xaml

<UserControl x: Class = "CustomUISample.View.Editor.CustomEditor"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns: d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns: local = "clr-namespace: CustomUISample.View.Editor"
mc: Ignorable = "d"
d: DesignHeight = "450" d: DesignWidth = "800">
<UserControl.Resources>

<BooleanToVisibilityConverter x: Key = "BooleanToVisibilityConverter"/>

</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "30"/>
<RowDefinition Height = "40"/>
<RowDefinition Height = "1"/>
<RowDefinition Height = "*"/>
</Grid.RowDefinitions>

<Grid VerticalAlignment = "Center" Margin = "5,0">
<Grid.RowDefinitions>
<RowDefinition Height = "Auto"/>
<RowDefinition Height = "Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation = "Horizontal">
<Label Content = "View:"/>
<ComboBox Height = "23" Width = "150" Margin = "5,0">
<ComboBoxItem Name = "m_FormItem" Content = "Form" IsSelected = "True"/>
<ComboBoxItem Name = "m_GridItem" Content = "Grid"/>
</ComboBox>
</StackPanel>
</Grid>

<StackPanel Grid.Row = "1" Orientation = "Horizontal" VerticalAlignment = "Center" Margin = "10,0">
<TextBlock Text = "Name:"/>
<TextBlock Text = "{Binding Path = Name}" Margin = "5,0"/>
</StackPanel>

<Border Grid.Row = "2" BorderThickness = "0,1,0,0" BorderBrush = "LightGray" HorizontalAlignment = "Stretch"/>

<!-Form-like view->
<Grid Grid.Row = "3" Visibility = "{Binding ElementName = m_FormItem, Path = IsSelected, Converter = {StaticResource BooleanToVisibilityConverter}}" Margin = "10,20,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "50"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto"/>
<RowDefinition Height = "30"/>
<RowDefinition Height = "Auto"/>
</Grid.RowDefinitions>

<TextBlock Text = "Description:" VerticalAlignment = "Top" Margin = "0,2,0,0"/>
<TextBox Grid.Column = "1" Text = "{Binding Path = Description}" MinHeight = "150" HorizontalAlignment = "Stretch"/>

<TextBlock Grid.Row = "1" Text = "Class name:" VerticalAlignment = "Center"/>
<TextBlock Grid.Row = "1" Grid.Column = "1" VerticalAlignment = "Center" Text = "{Binding Path = ClassName}" Margin = "5,0" HorizontalAlignment = "Left"/>

</Grid>

<!-Grid view->
<DataGrid Grid.Row = "3" ItemsSource = "{Binding Path = Children}"
Visibility = "{Binding ElementName = m_GridItem, Path = IsSelected, Converter = {StaticResource BooleanToVisibilityConverter}}"
AutoGenerateColumns = "True" Margin = "10,20,10,0"
HorizontalScrollBarVisibility = "Auto"/>
</Grid>
</UserControl>
Custom Inspector

Defines a view in the Custom Inspector.

CustomInspector.xaml

<UserControl x: Class = "CustomUISample.View.Inspector.CustomInspector"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns: d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns: local = "clr-namespace: CustomUISample.View.Inspector"
mc: Ignorable = "d"
d: DesignHeight = "450" d: DesignWidth = "800">
<Grid>
<TextBlock Text = "{Binding Path = Name}"
VerticalAlignment = "Center" HorizontalAlignment = "Center"/>
</Grid>
</UserControl>
Custom Navigator

Defines a view for the custom navigator.

CustomNavigator.xaml

<UserControl x: Class = "CustomUISample.View.Navigator.CustomNavigator"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns: d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns: local = "clr-namespace: CustomUISample.View.Navigator"
xmlns: viewModel = "clr-namespace: CustomUISample.ViewModel.Navigator"
mc: Ignorable = "d"
d: DesignHeight = "450" d: DesignWidth = "800">
<UserControl.Resources>

<Style TargetType = "{x: Type TreeViewItem}">
<Setter Property = "OverridesDefaultStyle" Value = "False"/>
</Style>

<HierarchicalDataTemplate DataType = "{x: Type viewModel: CustomNavigatorItemViewModel}" ItemsSource = "{Binding Path = Children}">
<StackPanel Orientation = "Horizontal">
<Image Source = "{Binding Path = Icon}" Height = "16" Width = "16"/>
<TextBlock Text = "{Binding Path = Model.Name}" Margin = "5,0,0,0" VerticalAlignment = "Center"/>
</StackPanel>
</HierarchicalDataTemplate>
</UserControl.Resources>
<Grid>
<TreeView x: Name = "m_Tree" ItemsSource = "{Binding Path = Items}" SelectedItemChanged = "TreeView_SelectedItemChanged"
ScrollViewer.HorizontalScrollBarVisibility = "Disabled"/>
</Grid>
</UserControl>

Implements the view behavior of the custom navigator.

CustomNavigator.xaml.cs**

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CustomUISample.ViewModel.Navigator;

namespace CustomUISample.View.Navigator
{
///<summary>
///Interaction logic of CustomNavigator.xaml
///</summary>
public partial class CustomNavigator: UserControl
{
public CustomNavigator ()
{
InitializeComponent ();
}

///<summary>
///Change tree selection
///</summary>
///<param name = "sender"> </param>
///<param name = "e"> </param>
private void TreeView_SelectedItemChanged (object sender, RoutedPropertyChangedEventArgs <object> e)
{
var vm = DataContext as CustomNavigatorViewModel;
var itemVM = m_Tree.SelectedItem as CustomNavigatorItemViewModel;
if (itemVM! = null)
{
vm.SelectedItem = itemVM.Model;
}
}
}
}

Add custom editor view

Add a custom editor to the view of the target model.

Operation procedure
  1. Select the target model for which you want to display the custom editor in the model navigator.
  2. Select Add View from the context menu.
  3. The custom editor included in the view addition candidates is displayed under the name of [Custom Editor]. Select it and add the view.
  4. If you switch to the view added in the main editor, you can view and edit the target model in the built-in custom editor.