How to open screen with the name of screen ?

A forum devoted to the discussion of all topics having to do with scripting and other advanced programming using iX Developer.
Arnaud J.
Posts: 6
Joined: Mon Sep 19, 2011 4:51 am

How to open screen with the name of screen ?

Post by Arnaud J. »

Hello,
I need to open a screen from string like this "Neo.ApplicationFramework.Generated.Screen1", where "Screen1" is the name of the screen, how to do that ?
The screen to open can change dynamically, so I cannot used the code Globals.Screen1.Show();

I need a function like this :

void ShowByScreenName(string strScreenName);

Sorry for my English,

Thanks for you help,

Arnaud

User avatar
Ron L.
Posts: 214
Joined: Fri Jul 15, 2011 3:21 pm

Re: How to open screen with the name of screen ?

Post by Ron L. »

Arnaud,

Here is the approach I would take to dynamically change screens at run-time.

I would create a Tag and use it to select different screens. The tag can be mapped to to an address on a PLC if that makes more sense for your system. For this example, I'll call the tag, "ScreenTag".

Click on the [...] button under the "Action" column.
tag_action.jpg
tag_action.jpg (82.58 KiB) Viewed 30796 times
Here you can configure the properties of the "ScreenTag" to change screens depending on the value of the tag. For the attached screen shot, if I wanted to change to "Screen1", I would set the "ScreenTag" to be a value of 1.
screen_dynamic_tag_props.jpg
screen_dynamic_tag_props.jpg (69.67 KiB) Viewed 30796 times
If you now wanted to change to "Screen1" using script, the code would look like this.

Code: Select all

Globals.Tags.ScreenTag.Value = 1;
Best Regards,

Beijer Electronics, Inc.
Ron Lloyd | Applications Engineer

Arnaud J.
Posts: 6
Joined: Mon Sep 19, 2011 4:51 am

Re: How to open screen with the name of screen ?

Post by Arnaud J. »

Hi Ron,

I would like something more generic, because tomorrow if I add a new screen I should not forget to change the screen tag, so your solution is not very good for the "maintenance" of the project. I should modify something like 60 screens to implement your solution...
So if you have a function to open a screen with the screen name it's better for our project.

Thanks,

User avatar
Ron L.
Posts: 214
Joined: Fri Jul 15, 2011 3:21 pm

Re: How to open screen with the name of screen ?

Post by Ron L. »

There should be a way to do what you're asking for with the C# Reflection classes. I'll look into this in the next couple days and see if I can come up with some sample code. I've done something similar before where I converted strings to Tags.
Best Regards,

Beijer Electronics, Inc.
Ron Lloyd | Applications Engineer

User avatar
Ron L.
Posts: 214
Joined: Fri Jul 15, 2011 3:21 pm

Re: How to open screen with the name of screen ?

Post by Ron L. »

Here is some code I placed inside a Scrip Module that will do what you're looking for.

Code: Select all

//--------------------------------------------------------------
// Press F1 to get help about using script.
// To access an object that is not located in the current class, start the call with Globals.
// When using events and timers be cautious not to generate memoryleaks,
// please see the help for more information.
//---------------------------------------------------------------

namespace Neo.ApplicationFramework.Generated
{
    using System.Windows.Forms;
    using System;
    using System.Drawing;
    using Neo.ApplicationFramework.Tools;
    using Neo.ApplicationFramework.Common.Graphics.Logic;
    using Neo.ApplicationFramework.Controls;
    using Neo.ApplicationFramework.Interfaces;
	
	using Neo.ApplicationFramework.Generated;		
	using System.Reflection;
    
    public partial class ScriptModule1
    {
		public static void ShowScreen(string name)
		{
			IScreenAdapter scrn = StringToScreen(name);
			if (scrn == null) {
				return;
			}
			scrn.Show();
		}
		
		private static IScreenAdapter StringToScreen(string name)
		{			
			Type globalType = typeof(Globals);
			Type iAdaptType = typeof(IScreenAdapter);
			foreach (var p in globalType.GetProperties())
			{				
				if (p.PropertyType.Name.Equals(iAdaptType.Name) &&
					p.Name.Equals(name))
				{
					return (IScreenAdapter)p.GetValue(globalType, null);
				}
			}
			return null;
		}
    }
}
The code to use the ShowScreen function looks like this.

Code: Select all

ScriptModule1.ShowScreen("Screen2");
Best Regards,

Beijer Electronics, Inc.
Ron Lloyd | Applications Engineer

User avatar
Ron L.
Posts: 214
Joined: Fri Jul 15, 2011 3:21 pm

Re: How to open screen with the name of screen ?

Post by Ron L. »

On a related note, here's a function to convert a String to an existing Tag.

Code: Select all

// returns null if tag not found
		public GlobalDataItem StringToTag(string tagName)
		{
			string typeName = (new GlobalDataItem()).GetType().Name;
			PropertyInfo[] props = Globals.Tags.GetType().GetProperties();
			foreach (PropertyInfo prop in props) {
				if (prop.PropertyType.Name.Equals(typeName)) {
					if (prop.Name.Equals(tagName, StringComparison.CurrentCultureIgnoreCase)) {
						return (GlobalDataItem)prop.GetValue(Globals.Tags, null);
					}					
				}
			}
			return null;
		}
Best Regards,

Beijer Electronics, Inc.
Ron Lloyd | Applications Engineer

Arnaud J.
Posts: 6
Joined: Mon Sep 19, 2011 4:51 am

Re: How to open screen with the name of screen ?

Post by Arnaud J. »

Thanks for your response, that works fine.

val_pilats
Posts: 9
Joined: Tue Jan 17, 2012 2:47 am

Re: How to open screen with the name of screen ?

Post by val_pilats »

Hi Ron! I'm trying to use Your script convert String to Tag, but IX throws error like "The type or namespace name GlobalDataItem could not be found.....".

P.S. added
using Neo.ApplicationFramework.Generated;
using System.Reflection;
the same error.

What kind of library should I add?

val_pilats
Posts: 9
Joined: Tue Jan 17, 2012 2:47 am

Re: How to open screen with the name of screen ?

Post by val_pilats »

val_pilats wrote:Hi Ron! I'm trying to use Your script convert String to Tag, but IX throws error like "The type or namespace name GlobalDataItem could not be found.....".

P.S. added
using Neo.ApplicationFramework.Generated;
using System.Reflection;
the same error.

What kind of library should I add?
Figured out.

using Neo.ApplicationFramework.Tools.OpcClient;

User avatar
Ron L.
Posts: 214
Joined: Fri Jul 15, 2011 3:21 pm

Re: How to open screen with the name of screen ?

Post by Ron L. »

Came up with some code related to this topic to display a Screen or an Alias of a screen using strings.

Code: Select all

namespace Neo.ApplicationFramework.Generated
{
    using System.Windows.Forms;
    using System;
    using System.Drawing;
    using Neo.ApplicationFramework.Tools;
    using Neo.ApplicationFramework.Common.Graphics.Logic;
    using Neo.ApplicationFramework.Controls;
    using Neo.ApplicationFramework.Interfaces;
    
	using System.Reflection;
    
    public partial class Screen1
    {		
		void Button1_Click(System.Object sender, System.EventArgs e)
		{		
			ShowAlias("Screen1", "Instance1");
			return;		
		}	
		
		//find screen with specified name and display
		public static void ShowScreen(string screenName) {
			try {
				Type gType = typeof(Globals);
				PropertyInfo pInfo = gType.GetProperty(screenName);
				MethodInfo mInfo = pInfo.PropertyType.GetMethod("Show", new Type[0]);
				var scrnObj = pInfo.GetValue(gType, null);
				mInfo.Invoke(scrnObj, null);
			}
			catch (Exception ex) {
				MessageBox.Show("ShowScreen method failed. Check screen name. " + ex.Message);
			}
		}
		
		//show alias with specified name
		public static void ShowAlias(string screenName, string aliasName)
		{
			try {
				Type gType = typeof(Globals);
				PropertyInfo piScrn = gType.GetProperty(screenName);
				var scrnObj = piScrn.GetValue(gType, null);			
				PropertyInfo piAlias = piScrn.PropertyType.GetProperty(aliasName);			
				MethodInfo mInfo = piAlias.PropertyType.GetMethod("Show", new Type[0]);
				var aliasObj = piAlias.GetValue(scrnObj, null);
				mInfo.Invoke(aliasObj, null);
			}
			catch (Exception ex) {
				MessageBox.Show("ShowAlias method failed. Check screen and alias names. " + ex.Message);
			}			
		}		
    }
}
Best Regards,

Beijer Electronics, Inc.
Ron Lloyd | Applications Engineer

Post Reply