The Difference Between IScreenObject and IActiveScreen (plus a cool technique)
Feb
16
Written by:
Thursday, February 16, 2012 1:29 PM
In a
recent post in the
LightSwitch Forum,
Justin Anderson (a member of the LightSwitch Team) briefly but succintly explained the difference between the IScreenObject and IActiveScreen interfaces.
Not only did he explain the difference between the two, he also used a neat little LINQ trick, involving the Select method, that I don't think I've seen before. Or at least if I have, I don't remember seeing it.
I felt that these two things were important enough to quickly blog about.
Justin's explanation:
"All of the screens that you create in LightSwitch implement the IScreenObject interface, whereas what is returned from Application.ActiveScreens is an enumerable of IActiveScreen. Each IActiveScreen object has a reference to the IScreenObject object to which it corresponds".
In B1, Application.ActiveScreens used to return an IEnumerable(Of IScreenObject), whereas from B2 on, it returns an IEnumerable(Of IActiveScreen). This meant that you often needed to cast each IActiveScreen.Screen to IScreenObject before you could use the IScreenObject's methods.
Justin's cool technique shows us a way of getting the "Screen" property from each of the IActiveScreens in Aplication.ActiveScreens, without having to do an explicit type cast inside any loop that may be opeating on the ActiveScreens collection.
The technique involves simply using LINQ's
Select method, so you get an IEnumerable(Of IScreenObject), instead of an IEnumerable(Of IActiveScreen), all in one statement. The description for Select is "Projects each element of a sequence into a new form".
So, instead of:
VB:
Dim screens = Application.ActiveScreens
For Each s In screens
's is an IActiveScreen, so we need to cast it before we can work with it
dim screen = Ctype(s.Screen, IScreenObject)
'do something with screen
Next
C#:
var screens = Application.ActiveScreens;
foreach (var s in screens)
{
//s is an IActiveScreen, so we need to cast it before we can work with it
var screen = (IScreenObject)s.Screen;
//do something with screen
}
You only need:
VB:
Dim screens = Application.ActiveScreens.Select(Function(s) s.Screen)
For Each screen In screens
'screen is already an IScreenObject, so no type casting needed
'you can work directly with screen
Next
C#:
var screens = Application.ActiveScreens.Select((s) => s.Screen);
foreach (var screen in screens)
{
//screen is already an IScreenObject, so no type casting needed
//you can work directly with screen
}