apps meeting 2010 travis armstrong cyle nelson january 2010 advanced c# customization training

Post on 27-Dec-2015

218 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Apps Meeting 2010Travis ArmstrongCyle NelsonJanuary 2010

Advanced C# Customization Training

Advanced C# Customization

• Prerequisites:– It’s assumed you already know what’s being taught in

the Intro session:• Basics of C# and Object Oriented Programming

– Namespaces, objects, scope– C# Syntax, operators, loops

• C# Program object in ACE– Referencing workspace objects, executing

• Debugging– Using the Event Log and MessageBox

• How to do useful things– Read servo data, log to a file

• Have Visual Studio installed and ready to go

• If not, you’re in the wrong room!

Advanced C# Customization

• What is a Plug-in• Custom Ace Object

– Creating an object– Editor Attributes– Serialization– Custom Editor

• GUI Plug-in• Other Topics

– Collections– GUI Design

• Example– V+ Task Profiler

What is a Plug-in?

• Plug-ins add functionality to Ace• Basic concepts

– Custom object• Server-side• Data container• Combination of other objects

– GUI Plug-in• Client-side• Display information• Interact with server

– More advanced combinations• Some GUI items could create server-side objects

– Example: V+ Task Profiler

Other customization

• Custom Operator Interface (or Client)– Not a Plug-in to Ace– Separate from the Ace client or server– Connects to an existing AceServer– Not part of today’s discussion

• Custom application– Host the AceServer internally– All implementation done in Visual Studio– OEM-type applications (rare)

Our Focus

• Today’s session– Server-side Plug-in

• Custom Ace Object• Making something simple• Custom Object Editor

– Client-side Plug-in• GUI Plug-in• Hooking in to the client• Accessing a server-side object

Ace Assemblies

• DLL’s in the Ace “bin” directory are loaded when ACE starts– C:\Program Files\Adept Technology\Adept ACE\bin

• Attributes indicate what Ace should do with it– In AssemblyInfo.cs:

• [assembly: Ace.AceAssembly]• Used to register as an ACE Plug-in

Creating a Custom Ace Object

• Exercise 1:– Create a new object Plug-in

Getting Started

• Start Visual Studio, create a new project– Class Library

• Add Reference to Ace dll– Ace.Core.dll

• Mark it as an Ace Plug-in in AssemblyInfo.cs– [assembly: Ace.AceAssembly]

• Your class is called “Class1.cs”

namespace CustomAceObjectSample001 { public class Class1 { }}

Making the Object

• Ace needs to know what you’re creating– In this case, it’s a workspace object– All workspace objects are derived from the base class

AceObject– So, your class needs to inherit from AceObject

• Ace needs to know where to display the object– This is called the Picklist– Attribute Ace.Gui.PickList()– String that defines where the object is– You can use the existing ones, or make your own

public class Class1 : AceObject {

[Ace.Gui.PickList("CustomObject|Sample")]

Test the object

• Build the library– From the VS menu Build>Build Solution– F6

• Copy the dll to the Ace folder– C:\Program Files\Adept Technology\Adept ACE\bin

• Run ACE

Creating a Custom Ace Object

• Exercise 1:– Create a new type of object– Make it available in the “CustomObject” picklist– Test it

• It doesn’t do much yet, does it?

Sidebar: Visual Studio tricks

• Instead of building your project, then copying the dll to the Ace /bin/ folder– Project properties– Build Events– Post-build command

– copy "$(TargetPath)" "C:\Program Files\Adept Technology\Adept ACE\bin“

– When you build, it will copy the dll to the folder

Sidebar: Visual Studio tricks

• Visual Studio Professional– Debug

• Start external program• When you press F5

– Builds project, copies dll to Ace /bin/ folder– Starts Ace with your dll in Debug mode– Breakpoints, debugging, etc

• Only available in Visual Studio Pro– You must disable the “LoaderLock” exception– In Debug->Exceptions, under “Managed Debugging Assistants”

Give it a Property

• Property vs Field– A Field is the variable within a class

– A Property is the way the variable is accessed from outside (an accessor)

– With Properties, you can easily change the accessibility• For Read-Only, don’t implement ‘set’

– ACE will automatically display public Properties in the PropertyGridEditor, but not Fields

public string text;

private string text;

public string Text { get { return text; } set { text = value; }}

Creating a Custom Ace Object

• Exercise 2:– Add a private Field– Add a public Property that gets and sets the Field– Test it

PropertyGrid Editor

• Default Editor– Automatically

displays public Properties

– Name is the exact text of the Property

– Description is empty– Category is

“Configuration”

DescriptionAttribute

DisplayName

DisplayName, Description, and Category can be customized with attributes

Category

Property Attributes

• You can enter custom attributes for the Property directly in the C# code

• Attributes– Require System.ComponentModel (using)– DisplayName

• What is displayed in the editor– DescriptionAttribute

• Helpful text displayed at the bottom– Category

• Helps sort the properties in the editor

[DisplayName(“Text Property”)][DescriptionAttribute(“This is a custom text property”)][Category(“Miscellaneous Category”)]public string Text { get { return text; } set { text = value; }}

Creating a Custom Ace Object

• Exercise 3:– Give your Property custom attributes

• Display Name• Description• Category

• Save the workspace• Why did this happen?

Serialization

• Serialization is the process of converting object data to a storage format– ACE uses XML Serialization

• “Human readable” (sort of)

• Workspace objects need to be serialized so they are saved with the workspace, and can be reconstructed later

• Object classes need the Serializable attribute– Even if the data isn’t being stored

– If the data is being stored, you must also implement the methods to do this

[Serializable]public class Class1 : AceObject {

Serialization Methods

• When the workspace is saved, ACE requests data from every object in the workspace, then writes the file– GetObjectData

• When a workspace is loaded, ACE creates objects using that data– Custom constructor

Serialization (Saving)

• Override the GetObjectData method– Add “using System.Runtime.Serialization”

– If you type in “public override void G…” Visual Studio will enter the rest for you

– Add lines to save the data in your own object• Info.AddValue(string name, data)

– Name is whatever name you choose to save it under Only used for saving and loading the object

– Data can be any data type (string, boolean, double, object, etc)

• Add all data from the object that you want to store

public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context);}

info.AddValue("Text", text);

Serialization (Saved Data)

• When you save the workspace, the object data is written to the file– You can open ACE workspace files and see the

serialized data

<a1:Class1 id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/CustomAceObjectSample001/CustomAceObjectSample001">

<Name id="ref-3">Sample</Name><Text id="ref-4">hello world</Text>

</a1:Class1>

Serialization (Loading)

• You must create a specific constructor to load the object

– Get the values out of the info object• Info.GetBoolean(string name)• Info.GetString(string name)• Info.GetDouble(string name)• Info.GetValue(string name, Type type)

– Returns an object that can be cast into any type– For instance, if you have made a custom data container class

or have a more complex class– Must be cast into the correct type

• You must also create a basic parameterless constructor

protected Class1(SerializationInfo info, StreamingContext context) :base(info,context) { text = info.GetString("Text");}

public Class1() { }

Creating a Custom Ace Object

• Exercise 4:– Implement Serialization methods to save and load

your object data– Test it

Custom Object Editor

• By default, ACE will use a PropertyGrid to display the public Properties of the class

• You can create your own class-specific editor

Custom Object Editor

• Add a User Control to the project– Right click on the project– Add -> User Control– Name it something useful (CustomObjectEditor)

Custom Object Editor

• You are looking at the design mode– Note [Design] in the tab

• Open the code view

• Change “UserControl” base class to “DefaultObjectEditor”– Add “using Ace.Gui”

public partial class CustomObjectEditor : DefaultObjectEditor {

Custom Object Editor

• Add something useful to the Designer– Since we’re just using a Text field, add a TextBox– Position and size it if you want– Look at the properties

• Now, we need to link the Text property of the object to the text box, in two ways– When the editor is opened, the Text property should

be displayed in this TextBox– When the text in the TextBox is modified, the object

property should be updated

Custom Object Editor

• Display the object text when the editor is opened:– Find the “Load” event of the Control– Click on the control (not the TextBox)– Open the Properties window– Click on the Events button– Find the Load event

• Double-click on it to automatically generate code

– Inheriting from DefaultObjectEditor gives us SelectedObject

• When the editor is opened, SelectedObject is passed in• It’s type is object, so it must be explicitly cast:

private void CustomObjectEditorSample_Load(object sender, EventArgs e) {

}

textBox1.Text = ((Class1)SelectedObject).Text;

Custom Object Editor

• Update the object text when the control is modified– Find the TextBox event TextChanged

– Now, whenever the text is modified in the textbox, the object will be updated

• Only one more step to go

((Class1)SelectedObject).Text = textBox1.Text;

Custom Object Editor

• Reference the editor in the object class– ACE needs to be told that this is the editor to use

whenever the object is opened– Mark the class with the ObjectEditor attribute

• You may need to add “using Ace.Gui”

[ObjectEditor(typeof(CustomObjectEditor))]public class Class1 : AceObject {

Custom Object Editor

• Exercise 5:– Test your custom editor

• Take a break

GUI Plug-in

• Two aspects of a GUI Plug-in1. The control itself that is displayed

• Graphical user control

2. The client-side assembly• Registers the control• Defines how it is displayed

GUI Plug-in (User Control)

• Add a new Item to your Visual Studio solution– User Control, name it GuiPluginControl.cs

• Add a Label to the control

GUI Plug-in (Assembly)

• Add a class to the project– GuiPluginClass.cs

• Inherit from IAceClientPlugin– Add “using Ace”

• Build the project– What happened?

• What is this error?– IAceClientPlugin requires that certain methods be

implemented

“GuiPlugin does not implement Initialize()”“GuiPlugin does not implement Dispose()”

Required methods

• Initialize()– Called during client startup– Connect to the Ace Client Editor context– Add an item to the pulldown menu– Add an event handler

• Dispose()– Called during shutdown– Release any resources

class GuiPluginClass : IAceClientPlugin {

public void Initialize() {}public void Dispose() {}}

GUI Plug-in

• Add the Initialize() and Dispose() methods– Add “using Ace.Gui”, “using System.Windows.Forms”

• Initialize:// Reference the Editor ContextIGuiHost guiHost = AceClient.Instance.EditorContext;

// Create instance of the User Control Plug-inGuiPluginControl control = new GuiPluginControl();

// Add the User Control to the dockable windowguiHost.AddContent(control, "Custom User Control", null);

// Add an event handler to display the windowEventHandler handlerPlugin = delegate { guiHost.SetContentVisible(true, control);};

// Reference the "View" pull-down menuToolStripMenuItem menuItem = (ToolStripMenuItem)guiHost.PulldownMenuStrip.Items["ViewMenu"];

// Add an item to the pull-down menumenuItem.DropDownItems.Add("My Custom Gui Plugin", null, handlerPlugin);

GUI Plug-in

• Dispose() method can be empty• Build the project, and run it• Exercise 6:

– Tie the Custom Object and GUI Plug-In together• Add a button to the Control• When clicked, read the value of an object in the

workspace

GUI Plug-in

• Create the button• Double click the button to add Click event handler

private void button1_Click(object sender, EventArgs e) { // Reference the AceServer AceServer server = AceClient.Instance.AceServer; // Get the object in the workspace Class1 customObject = server["Custom Object"] as Class1; // Make sure it exists before reading the text property if (customObject != null) { label1.Text = customObject.Text; }}

GUI Plug-in

• Run your project– Click the Read button– Does it work?

• The object path must be exactly correct!

Other Topics

• Collections– Array– List– Dictionary

• Gui Plug-ins – things to keep in mind• Resource Files

– GuiText– PropertyGrid– EnumText

Array

• Arrays in C# are like most other programs• Defined type, can be multidimensional• Must declare with size

• Assign elements by integer index

• Loop through them using for or foreach

• Sort

string[] stringArray = new string[5];

stringArray[0] = "item 0";

for (int i = 0; i < stringArray.Length; i++) { stringArray[i] = "item " + i.ToString();}

foreach (string item in stringArray) { ace.AppendToLog(item);}

Array.Sort(stringArray);

type[]

List

• List is like an Array, but allows dynamic sizing• Don’t have to declare size

• Easily add items• New items are added to the end

• Access by index

• Find a specific entry

• Loop using foreach

• Sort

List<string> stringList = new List<string>();

stringList.Add("item 0");

stringList[0] = "test";

int location = stringList.IndexOf("item 0");

stringList.Sort();

foreach (string item in stringList) { MessageBox.Show(item);}

List<type>

Dictionary

• Dictionary has key and value• key can be any type• value can be any type

• Can add new elements, refer by index

• Can be very complex relationships

Dictionary<key,value>

Dictionary<int, string> strings = new Dictionary<int, string>();

strings[0] = "item 0";strings.Add(1, "item 1");

Dictionary<AceObject, string[]> objectStrings = new Dictionary<AceObject, string[]>();

Other Topics - Versioning

• Plug-ins reference ACE modules (dlls)• Dll reference must match the version of ACE that is running• Dlls change with each version of ACE

• A Plug-in built for 2.2.2.1 will only work with 2.2.2.1• You must build a new Plug-in whenever you upgrade ACE

• This applies to 2.0, 2.1, 2.2• Changes in 3.0

– Reference will change (Ace.Core.Common instead of Ace.Core)

Other Topics – GUI design

• GUI Design– Resolution

• What looks great on your laptop might not work on a user’s low-res monitor

– Display settings• Windows settings

– “Classic style” vs XP style– Dpi settings (affects font size)

– The next 3 slides are all on the same screen, same resolution

My “normal” settings

Changed dpi

Notice the text doesn’t fit correctly

“Classic” Windows settings

V+ Task Profiler

V+ Task Profiler

• GUI Plug-in– Inherits from IAceClientPlugin– Adds a button to the Toolstrip– Monitors controller connection and Selected Link

• Disables button if controller disconnected or link changed to a disconnected controller (or iCobra)

• When the button is clicked, starts a multithreaded server-side Data management object

– Downloads V+ programs to controller & starts them– Listens for V+ to establish connection

V+ Task Profiler

• V+ programs read the task profile data and send to the Server object

• Server object receives and parses data• Server object raises an event to notify the GUI

object that the data is ready to display• GUI object updates graph

Profiler Startup

Registers the controlCreates the buttonMonitors controller status

When the button is clicked, creates the control

Creates the server-side data objectDisplays the graph

Downloads V+ programsStarts V+ programsSpawns new thread to listen for response

Listens for connection from V+

Profiler Runtime

Reads profiler informationSends up to PC

Unpacks dataSends to ProfileDataServer

Compiles dataConverts to display formatRaises event for UI

Updates graph displayMonitors user requests (display all tasks)

Monitors controller statusMaintains Dictionary of all open Profiler windowsHandles disconnect/close events

V+ Task Profiler

Advanced C# Customization

• Reminder– Systems Group is here to help you– Resource for samples, advice, etc

• Feature requests come from AE’s– AIM Plug-Ins designed by AE’s– Many showed up in later versions of AIM

• Questions

top related