AVEVA OMI Software Developer Kit
App Editor Configuration

The AppConfig SDK lets you configure all areas of an editor, including the command bar and the main area. You will have to define three things as you build your editor:

  • View: This is the area below the title bar and is the main window of the editor.
  • The contents of the view: Also referred to as the activity, the activity defines the UI, how configuration data is saved to an app object, and how the data is loaded to the app at run time. An editor always contains at least one activity (main activity editor). If your app editor defines multiple activities, you will add activity tabs that appear in the title bar, above the view.
  • The activity tab(s): The activity tab defines data sources, the UI, and the configuration page. Each activity tab is independent within the editor. Thus, if your editor has multiple activities, each one is an independent editor that defines different aspects of your app.

Activities

The AppConfig framework provides the core capabilities for your editor (activity), and provides the ability to save and close an app, to launch a window, etc. Each activity needs to know what information has to be saved in the app and what information gets loaded into the app at run time. Configuration information is saved into the app object itself (within the IDE), and then at run time, the configuration information is extracted from the app object and uploaded to the run-time app. When a configuration change is detected (object is dirty), the save, save and close, and close options will be enabled within the title bar. You will have to define the file name, file format (for example, json, xml, text file, etc.), and file location for saving the configuration information.

Keep in mind that an app editor can encompass multiple editors (activities). You can choose to have each activity create its own configuration file, or use a single configuration for all activities.

Load and Save

The following sample illustrates how to implement load and save in the main activity:

Implement Load and Save
Copy Code
public class MyOMIAppConfigEditor : IEditorConfig
{
       
   public void InitializeEditor(IEditorBase editor)
   {
      this.editor = editor;
      this.mainActivity = new MyOMIAppMainActivityViewModel(this.editor);
   }
   public IEnumerable<IEditorActivity> GetActivities()
   {
      return new IEditorActivity[] { this.MainActivity };
   }
   public void Load(Dictionary<string, byte[]> appData)
   {
      this.mainActivity.Load(appData);
   }
 
   public Dictionary<string, byte[]> Save()
   {
      return this.mainActivity.Save();
   }
}

EditorActivityViewModelBase

You will also have to implement the EditorActivityViewModelBase class. Your main activity is derived from this class. If you are implementing multiple activities, use the Label property to add tabs on the title bar for each activity.

 

Label Property
Copy Code
public virtual string Label
  {
  get { return Properties._string.Label; 
   }

Define Views and View Models

You can customize Views and View Models as needed within your editor. You will need to add one View Model and View for each activity, on a one to one to one basis. Only one instance of an editor that defines the App Editor UI is required to contain all activities, Views, and View Models. You can associate the View and View Model within the WPF framework. There are many options for doing this association. For example, to define a View Model:

Generic.xaml
Copy Code
<DataTemplate DataType="{x:Type omiAppEditor:EditorMainActivityViewModel}">
    <view:AppEditorView />
</DataTemplate>


Read-Only Mode

The framework also exposes the read-only mode, but you must add this to your editor. You will have to add code get the status of the app object from the UI and disable the UI in your editor if the app object is opened as read-only. Use the isReadOnly property, which gets a value that indicates whether or not object is in IsReadOnly state.

IsReadOnly
Copy Code
public virtual bool IsReadOnly { get; private set; }

AppManifest.xml File

The AppManifest.xml file is a requirement if you are adding an editor for your app. See AppManifest.xml File for additional information about this file. You must define two items in the AppManifest file:

  • AssemblyName: This is the same as the namespace (name of the dll, minus the dll extension).
  • EditorFullName: This is the fully qualified class name of the type that implements the IEditorConfig interface. It is the namespace plus the name of the control.
AppManifest.xml
Copy Code
<AppManifest AppVersion="6.0.0" ToolkitVersion="2.0.0" DesignTimeVisible="true">
   <Filters>
   </Filters>
   <Editor AssemblyName="ArchestrA.Visualization.MyOMIAppEditor" EditorFullName="ArchestrA.Visualization.MyOMIAppEditor.MyOMIConfigEditor">
   </Editor>
</AppManifest>

IEditorActivity

The basic framework commands are Save, Save/Close, and Close. To implement additional commands, use the RegisterCommands() method from the IEditorActivity interface. This editor also contains the CanCloseEditor() method (this method is also available in IEditorViewModelBase). You may want to add commands for validations based on business logic, such as checking if a user has entered a valid URL syntax, and block saving or closing the editor if the property does not validate.

IEditorActivity Methods
Copy Code
public virtual void RegisterCommands()
{
   ResourceDictionary icons = new ResourceDictionary() { Source = GetResourceUri((typeof(SampleActivity).Assembly), "Resources/Icons.xaml") );
   DrawingBrush comIcon1 = icons[
public virtual bool CanCloseEditor()
{
   return true;
}

Using Security

You can add security to your app by adding a secure login capability. The following code sample outlines how to do this.

SecureLoginSampleApp
Copy Code
namespace SecureLoginSampleApp
{
    using MyViewApp = ArchestrA.Client.MyViewApp;
    /// <summary>
    /// Interaction logic for SecureLoginViewSample.xaml
    /// </summary>
    public partial class SecureLoginViewSample : UserControl
    {
        public SecureLoginViewSample()
        {
            InitializeComponent();
            this.Loaded += SecuritySampleApp_Loaded;
        }
        private void SecuritySampleApp_Loaded(object sender, RoutedEventArgs e)
        {
            this.DataContext = new SecureLoginSampleVM();
            SecureLoginSampleVM vm = this.DataContext as SecureLoginSampleVM;
            if (vm != null)
            {
                vm.Initialize();
            }
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyViewApp.Security.ShowLoginDialog();
        }
        private void Logout_Click(object sender, RoutedEventArgs e)
        {
            MyViewApp.Security.Logout();
        }
    }
}