Page 1 of 2

How to open screen with the name of screen ?

Posted: Mon Sep 19, 2011 5:02 am
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

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

Posted: Mon Sep 19, 2011 1:41 pm
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 31681 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 31681 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;

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

Posted: Tue Sep 20, 2011 12:01 am
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,

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

Posted: Tue Sep 20, 2011 4:57 am
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.

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

Posted: Wed Sep 21, 2011 4:27 pm
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");

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

Posted: Wed Sep 21, 2011 4:30 pm
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;
		}

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

Posted: Thu Sep 22, 2011 1:08 am
by Arnaud J.
Thanks for your response, that works fine.

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

Posted: Tue Feb 07, 2012 3:56 am
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?

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

Posted: Fri Feb 10, 2012 6:58 am
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;

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

Posted: Mon Jan 21, 2013 3:41 pm
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);
			}			
		}		
    }
}