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 type Interface to be implemented in ViewModel Properties/methods that need to be implemented Custom Editor ICustomEditorView Descriptor Property
OnInitialized Method
OnBeforeDispose Method
ViewDefinitionId Property
SelectedItem property
SelectedItems property
SetModel method
GetDocumentContent method (*)Custom Navigator ICustomNavigator Descriptor Property
OnInitialized Method
OnBeforeDispose Method
SelectedItem Property
SelectedItems property
IsEnabled method
OnShow method
OnHide methodCustom Inspector ICustomInspector Descriptor 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 UIDeactivate
method: Deregister custom UI
API used for registration process
Target Callback Function Registration API Custom Editor RegisterCustomEditor Custom Navigator RegisterCustomNavigator Custom Inspector RegisterCustomInspector
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.
- In the Model Navigator, select the target model for your custom UI.
- Execute [Add View] from the context menu.
- Select the editor name for the custom UI you have included and add a view.
- 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
- 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 add | View class | ViewModel class |
---|---|---|
Custom Editor | CustomEditor | CustomEditorViewModel |
Custom Navigator | CustomNavigator | CustomNavigatorViewModel, CustomNavigatorItemViewModel (*) |
CustomInspector | CustomInspector | CustomInspectorViewModel |
(*) 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 add | Interface to be implemented in ViewModel | Properties/methods that need to be implemented |
---|---|---|
Custom Editor | ICustomEditorView | ViewDefinitionId Property SelectedItem Property SelectedItems Property SetModel Method GetDocumentContent Method |
Custom Navigator | ICustomNavigator | SelectedItem Property SelectedItems Property IsEnabled Method OnShow Method OnHide Method |
Custom Inspector | ICustomInspector | SetModel 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
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
Inspector ID Value Properties (model) CustomInspectorDescriptor.DisplayOrderModel 100 Related (model) CustomInspectorDescriptor.DisplayOrderRelationship 200 Diagram Definition CustomInspectorDescriptor.DisplayOrderDiagramDefinition 1000 Shape Definition (Node) CustomInspectorDescriptor.DisplayOrderNodeShapeDefinition 1100 Shape Definition (Port) CustomInspectorDescriptor.DisplayOrderPortShapeDefinition 1200 Shape Definition (Connector) CustomInspectorDescriptor.DisplayOrderConnectorShapeDefinition 1300 Form Definition CustomInspectorDescriptor.CustomInspectorDescriptor 2000 Form element (control) CustomInspectorDescriptor.DisplayOrderFormControlDefinition 2100 Form element (group) CustomInspectorDescriptor.DisplayOrderGroupDefinition 2200 Form element (grid) CustomInspectorDescriptor.DisplayOrderGridDefinition 2300 Form element (list) CustomInspectorDescriptor.DisplayOrderListDefinition 2400 Row Definition CustomInspectorDescriptor.DisplayOrderTreeGridRow 3100 Shape Definition (Lifeline) CustomInspectorDescriptor.DisplayOrderLifelineShapeDefinition 4100 Shape Definition (Note (Sequence)/Composite Fragment) CustomInspectorDescriptor.DisplayOrderSequenceNodeShapeDefinition 4200 Shape Definition (Message (Sequence)) CustomInspectorDescriptor.DisplayOrderMessageShapeDefinition 4300 Shape Definition (Note Anchor) CustomInspectorDescriptor.DisplayOrderNoteAnchorShapeDefinition 4400 Shape definition (execution specification/discard/message end) CustomInspectorDescriptor.DisplayOrderSequenceShapeDefinition 4500 Package CustomInspectorDescriptor.DisplayOrderPackage 10000 Metamodel (Class) CustomInspectorDescriptor.DisplayOrderClass 11000 Metamodel (related class) CustomInspectorDescriptor.DisplayOrderRelationshipClass 11100 Filelds CustomInspectorDescriptor.DisplayOrderField 12000 Enum CustomInspectorDescriptor.DisplayOrderEnum 13000 Reference: Display position of standard navigator
Navigator ID Value Model Navigator CustomNavigatorDescriptor.DisplayOrderModel 100 Product line navigator CustomNavigatorDescriptor.DisplayOrderProductLine 200 SCM Navigator CustomNavigatorDescriptor.DisplayOrderScm 300 Project Navigator CustomNavigatorDescriptor.DisplayOrderProject 400 Profile Navigator CustomNavigatorDescriptor.DisplayOrderProfile 500
Type descriptor
When you register your custom UI, you specify the type descriptor. The type descriptor defines static information for the custom UI.
Custom UI | Type descriptor | Information to define |
---|---|---|
Custom Editor | CustomEditorDescriptor | ID CustomEditorDefinitionDescriptor (*) |
Custom Navigator | CustomNavigatorDescriptor | ID Display name Display position Icon |
CustomInspector | CustomInspectorDescriptor | ID 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
- Select the target model for which you want to display the custom editor in the model navigator.
- Select Add View from the context menu.
- The custom editor included in the view addition candidates is displayed under the name of [Custom Editor]. Select it and add the view.
- 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.