Page 1 of 1

How can I have access to background screen objects?

Posted: Fri May 08, 2015 11:56 am
by iagoncalves
I've started an application and I created a screen with another screen in background. When the application is running the objects in the background screen are enabled.

I'd like to know how I can control the objects present in background screen by the main screen.

Thanks in advance!

Re: How can I have access to background screen objects?

Posted: Thu May 28, 2015 9:13 am
by AMitchneck
I don't know what you know about scripting, but you can use objects in the background screen like you would in the main screen via scripting control. iX developer sets a screen as a "background screen" by using the background screen as the base class for the main screen. As long as no objects are declared as private in the background screen, the main screen will be given access by the rights of inheritance.

Re: How can I have access to background screen objects?

Posted: Thu Jan 11, 2018 3:25 am
by ladin79
Hi,
I am using the following code placed in a scriptmodule called in a screen to access all his button controls:

public static void MyMethod(object screen)
{
System.Collections.Generic.List<Neo.ApplicationFramework.Controls.Button> buttons = GetLogicalChildCollectionVis<Neo.ApplicationFramework.Controls.Button>(screen);
foreach (Neo.ApplicationFramework.Controls.Button button in buttons)
{
..............
}
}


public static System.Collections.Generic.List<T> GetLogicalChildCollectionVis<T>(object parent) where T : DependencyObject
{
System.Collections.Generic.List<T> logicalCollection = new System.Collections.Generic.List<T>();
GetLogicalChildCollectionVis(parent as DependencyObject, logicalCollection);
return logicalCollection;
}

private static void GetLogicalChildCollectionVis<T>(DependencyObject parent, System.Collections.Generic.List<T> logicalCollection) where T : DependencyObject
{
IEnumerable children = LogicalTreeHelper.GetChildren(parent);
foreach (object child in children)
{
if (child is DependencyObject)
{
DependencyObject depChild = child as DependencyObject;
if (child is T)
{
logicalCollection.Add(child as T);
}
GetLogicalChildCollectionVis(depChild, logicalCollection);
}
}
}

My problem is that this screen have one other screen used as a background, my question is, how can I discriminate if a control belongs to the background screen or not? And how can I get the name of the background screen?

Thanks to any help!

Re: How can I have access to background screen objects?

Posted: Thu Jan 11, 2018 8:00 am
by AMitchneck
I'm assuming when you pass "screen" to your function you are passing "this". To extract the background screen so your function knows to ignore it, pass "base". If the object shows up in both this's and base's list you know it's in this's because it's in base's.

Re: How can I have access to background screen objects?

Posted: Thu Jan 11, 2018 9:29 am
by ladin79
Hi,
thanks for the answer, the problem is that if i pass base instead off this the compiler give this error:
“Use of keyword ‘base’ is not valid in this context”
I can’t understand why.

Re: How can I have access to background screen objects?

Posted: Fri Jan 12, 2018 10:47 am
by AMitchneck
You're right. I forgot base is only a keyword and thus can't be passed to functions. Where are you using this code? If it's from within the screen you can just pass "Globals.<background_screen_name>" for the background screen manually. If you want to do this programmatically, you would need to create a function that returns a screen based on the type and use screen.GetType().BaseType to get the type of the background screen.

I've never tried getting screen from type, but maybe this might work. It's a modification of a function I've used to get tag from name

Code: Select all

public static object GetBaseScreen(object screen)
{
   Type type = screen.GetType().BaseType;
   FieldInfo[] props = Globals.GetType().GetFields();
   foreach (FieldInfo prop in props) {
      if (prop.FieldType.Equals(type)) {
         return prop.GetValue(Globals);
      }
   }
   return null;
}
This code uses reflection - "using System.Reflection;".

Re: How can I have access to background screen objects?

Posted: Mon Jan 22, 2018 8:55 am
by andrea
I have a similar problem.

The code suggested didn't compile on this instruction

FieldInfo[] props = Globals.GetType().GetFields();

so I changed the function in this way

Code: Select all

public static object GetBaseScreen(object screen)
		{
			Type type = screen.GetType().BaseType;
			FieldInfo[] props = screen.GetType().GetFields();
			foreach (FieldInfo prop in props) {
				if (prop.FieldType.Equals(type)) 
					System.Windows.MessageBox.Show ( type.Name + ": " + prop.Name);
				else
					System.Windows.MessageBox.Show ( screen.GetType().Name + ": " + prop.Name);
			}
			return null;
		}
Calling this function no messages appear.
The sense was to loop each control and understand if belongs to main screen or parent screen?

Thank you

Re: How can I have access to background screen objects?

Posted: Mon Jan 22, 2018 9:33 am
by andrea
I think that

screen.GetType().GetFields();

does not populate the array

FieldInfo[] props

also using Globals.Name_Of_Real_Screen instead of screen parameter, same result

Re: How can I have access to background screen objects?

Posted: Tue Jan 23, 2018 9:56 am
by andrea
One of our problems with this hierarchy is we can have more controls having same name.

For example there could be a Button1 for Main Screen and one Button1 for or more Parent Screen (Base).

Since the system can distinguish one from the other, but I don't know how, we would like to discriminate them because we would like to apply, at runtime, some property to Button1 on the Main Screen but for example not to parent screens.

Re: How can I have access to background screen objects?

Posted: Thu Feb 01, 2018 11:06 am
by AMitchneck
Andrea,

I just got a chance to look at how iX compiles the Globals class. All screens are created as static IScreenAdapter which would explain why the code does not work. The code I wrote needs the screens being properties of the Globals class.

Using System.Reflection you can create your own instance of the background screen using the following.

Code: Select all

public static object GetBaseScreen(object screen)
{
   ConstructorInfo ci = screen.GetType().BaseType.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null);
   if (ci == null) return null;
   return ci.Invoke(new object[0]);
}