Today at lunch, we got on the subject of the WCF netTcpBinding and whether or not it was able to traverse routers (and even NAT). Highly nerdy lunch, admittedly.
So my co-worker Matthew and I decided to spend our RECESS this afternoon proving it out.
Here’s a picture of what we setup. A WCF service sitting out on the internet, and a client using WCF to call the service. The call goes out through a router that is doing NAT on the internal IP address of the client (192.168.1.*) and sending the message out to the service.
Service config:
<service name="NetTcpBindingTest.MathService" behaviorConfiguration="DefaultTcpBehavior">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBuffered"
name="netTcp" contract="Interfaces.IMath">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="mexTcp"
name="mexTcp" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8181/MathService" />
</baseAddresses>
</host>
</service>
Client ChannelFactory:
var math = ChannelFactory<Interfaces.IMath>.CreateChannel(
new NetTcpBinding( SecurityMode.None ),
new EndpointAddress( @"net.tcp://70.50.y.y:8181/MathService" ) );
Success! The netTcpBinding definitely makes it through the NAT router.
We weren’t done yet – next we added a callback interface into the mix, so the service could make out-of-band / unsolicited calls back to the client on the duplex channel binding. A bit surprising that this actually worked as well.
WCF Interfaces:
[ServiceContract( CallbackContract=typeof(IMathCallback))]
public interface IMath
{
[OperationContract]
int Add( int x, int y );
}
public interface IMathCallback
{
[OperationContract(IsOneWay = true)]
void AnotherAnswer( int z );
}
Client DuplexChannelFactory:
var math = DuplexChannelFactory<Interfaces.IMath>.CreateChannel(
new InstanceContext( this ),
new NetTcpBinding( SecurityMode.None ),
new EndpointAddress( @"net.tcp://70.50.y.y:8181/MathService" ) );
Moral of the story: netTcpBinding is router and NAT friendly. (MSDN docs actually say that it will work with some NAT routers, and there’s a TON of discussions about this on the internet, so your mileage may vary)
Disclaimer: InterKnowlogy is not in the business of writing gambling or casino games. This application was only written for research, with no intention of using it in a real gaming situation.
Here at InterKnowlogy, we have a program called RECESS (Research and Experimental Coding to Enhance Software Skills) – where we get to spend Wednesday afternoons working on whatever we want, to further our skill set, maybe in a technology area we don’t touch on our everyday projects. 
We’ve been writing apps for the Microsoft Surface table for a while, and I decided it would be cool to write a Craps game. One of the main ideas of the Surface table is to encourage multiple people to use an application simultaneously while sitting around the table. What better way to do that than to place bets, “roll” dice, and win “money”?
Before we get too far, check out the video of the game in action.
Now I’ll get into some of the cool design and implementation aspects of the application.
Tag Recognition
Obviously, you need to place bets to play craps. At a real craps table, you place bets with your chips on
the table, so in Surface Craps you do the same. We use a stack of chips taped together just so they’re easier to hold, and we use “object tags” stuck onto the bottom of the stack to uniquely identify you as a player. The Surface has cameras inside the case that recognize the object tag patterns and wake us up in event handlers with information about the tag that was placed. When your chip stack touches the table in a “bettable area” the bet is recorded, and a visual indication of your bet is added to the table. Up to 4 players can play at the same time, each having their unique stack of chips and placing bets on the table simultaneously.
Bettable Areas
I came up with a UserControl that I call a BettableArea that allows me to know if a tag (stack of chips) is placed somewhere on the table that allows bets (as opposed to dead space around the table, etc). This control’s content is a Path that defines the actual region that’s bettable (to allow for funny shapes) and also has 4 properties that are filled with the location where the virtual chips should be placed for each player in that region. The screenshot below shows the BettableArea controls with their opacity turned up to show them at design time – notice the curved and angled paths used to follow the actual betting zones.
A quick aside: on a real craps table, the dealers will place the chips for a player at a spot on a bettable area that’s related to where they are standing around the table. (if you’re at the right corner of the table, your bets will be at the right corner of the bettable area). When a bet is placed on my Surface Craps table, the visual chips representing your bet show up at one
of the 4 spots defined in the BettableArea control depending on which player you are.
Many craps players know that the “Place Odds” bet behind the Pass Line is the best bet in all of Vegas. So, YES, Surface Craps does support placing odds behind the pass line bet, and even enforces the fact that you can’t do it until a point has been established!
Ratchet Gesture
After you place your initial bet with your chips, we had to come up with an easy way to change the amount you’re betting. I came up with something I call the “Ratchet” gesture. You place your chips back down on the table over the existing virtual chips and I show a couple arrows on each side with the bet amount. While holding the chips down, you turn them left or right (say as if you’re unscrewing a bolt). As you turn, the bet amount is adjusted up or down depending on the direction of the turn.
3D Dice
I also used this application as a way to learn WPF 3D. Cubes are about the easiest object to make since they’re
square, and thus only require 2 triangles on each face. They material is semi-translucent to be able to see through the dice faces to the back of the opposing face. I use WPF animations to rotate the dice along 2 of the 3 axis when the user flicks the dice to “roll them”. The dice spin at a rate consistent with the force of the flick detected by the Surface cameras.
Rules / Payout Engine
I came up with a pretty straight forward architecture to allow me to process bets and payouts after each role. There is a BetLogicBase abstract class from which I derive a specific bet logic class for each type of bet (pass line, field, hardway, etc). They all implement the virtual ProcessRollResult( ) method, applying their specific logic for that type of bet, and determine what they should do with the bet they’re attached to: payout (win), remove chips (lose), or nothing. This design makes it super easy to generically process the bets after each roll. I just loop through all the BettableAreas and call ProcessRollResult( ) on any bets in that area.
On-Table Help
Instead of On-line help, I came up with “On-Table Help”. If you’re wondering how the hell to play c
raps, or can’t remember what the rules are for a particular bet, you just touch the faint question mark button next to that area, and up pops a ScatterViewItem with the information you’re looking for. Among other things, it tells whether it’s a single roll bet, or multi-roll, and what the payout table is.
Acrylic Dice
Finally and definitely one of the coolest features of the game are the acrylic dice. We only just got these dice in the last month, so until then you only play Surface Craps by flicking the virtual dice on the table. We got these dice that are transparent, and have nearly transparent byte tags on them. My understanding is that the IR sensitivity of the dots in the stickers on the dice is set so that the Surface cameras will recognize them. VERY COOL! 
So I recently went about implementing the ability to roll those physical dice on the table, and have it recognize which face they land on. I show a visual of the correct face of the dice under each physical die, and process results just as if the user had flicked the virtual dice.
Whew – long winded I know, but I’m super stoked on how this game came out. Take a look at the video if you haven’t already, and let me know what you think. Any ideas for other options or functionality in the game?
Thanks to Kevin Kennedy for the graphic design of the UI – he’s one of the InterKnowlogy graphic design studs. Another thanks to Joe Seymour who helped me with the betting/payout engine.
Disclaimer: InterKnowlogy is not in the business of writing gambling or casino games. This application was only written for research, with no intention of using it in a real gaming situation.
I have a setup project for a Windows service that we wrote some time ago. At the start of this current dev cycle, I upgraded the solution from VS 2008 to 2010 and went on my merry way to update code for the service (no changes to the installer). No big deal – all seemed well, … until I tried running the installer.
During install, we prompt for a username which we use to set ACLs on some files and directories. We do this by calling NTAccount.Translate like so:
SecurityIdentifier serviceAccountSid = (SecurityIdentifier)new NTAccount(serviceAccount).
Translate(typeof(SecurityIdentifier));
The user is prompted to enter their domain & username (i.e. myDomain\dhanan) and we translate that to a SID to set the file & folder permissions.
This all worked fine with the VS 2008-based installer, but then I spent WAY too much time yesterday debugging why it was failing now (exception: Some or all of the identity references could not be translated”. TFS source control confirmed that there were no source code changes involved other than the upgrade to VS 2010 (which actually did NOTHING to the setup .vdproj project file). Mysterious, huh?
I finally discovered that the issue was in the value coming from the installation custom dialog edit box where the user enters their domain and username. That value that gets added to the dictionary coming into the Installer.OnCommitted() method (via CustomActionData set to “/service_account=[EDITB1]” ).
When debugging into the Installer class and inspecting the value for the service_account, it had TWO backslashes in it (i.e. @"myDomain\\dhanan”), instead of 1 that I typed in as the user!
The lame thing about this is that it only does this in the VS 2010 setup project, not the VS 2008 one. The only thing I can find online that’s even loosely related is this: Troubleshooting Setup and Deployment Projects. (Backslash in textbox causes invalid directory or URL exception). They don’t mention WHY – I’m wondering if it’s the same issue.
So … I now have a hack at the top of the OnCommitted( ) method:
serviceAccount = serviceAccount.Replace( @"\\", @"\" );
Lame, but it works. Hey MS – please fix this !!
I’ve run into this before, and I ran into it again this week, so now I’m writing it down so that *we all* won’t forget about it next time. :)
I have an XML data provider class library that relies on the presence of an XML file to parse at runtime. I am writing tests for that data provider using Visual Studio test framework.
The issue is that the tests are run in the funny “TestResults” sub directories, by default named based on the date/time of the test run. When the test runs from this foreign directory, the test and data provider assemblies are copied there, but not the XML data file.
The Visual Studio test framework provides an attribute called DeploymentItem that you can use for just this issue. It allows you to mark a test with the attribute to describe that you need other items besides the assemblies for the test to run. In the example below, I’m specifying that from the unit test directory, go up and over (relative pathing) to the data provider directory and find the Data.xml file.
[TestMethod]
[DeploymentItem( @"..\UnitTestDeploymentItems\Data.xml" )]
public void TestMethod1()
{
var c = new SomeClass();
Assert.IsTrue( c.CanYouSeeTheFile() );
}
What they DON’T tell you, or at least I can’t find documented, are the other 2 things you have to do to get this to work.
#1 – the required file must be marked as Content & Copy (if newer/always). This is usually the case already, since I almost always need that file with the data provider assembly up to the consuming app directory.
#2 (and not obvious at all) – you must go into the .testsettings properties for the unit test and select “Enable Deployment”. Double click the .testsettings project (in the Solution Items folder) and select the Deployment item in the left side list.
There you have it – the test should now succeed, since the dependent file(s) are there are test runtime.
I had the privilege of working with Silverlight 4 pre-beta bits in preparation for one of the PDC keynote demos. One of the coolest new features just announced for SL is support for running in “full trust” out of browser. This allows full access to the machine from within the Silverlight code – you can communicate with other software on the machine, hardware devices, etc. (The user has to accept the OOB dialog with some extra text warning of the full trust setting)
Details
There is an XML file named OutOfBrowserSettings.xml that goes in the project properties folder. This file was first introduced for OOB in Silverlight 3. In SL4, there is one additional element:
<OutOfBrowserSettings.SecuritySettings>
<SecuritySettings ElevatedPermissions="Required" />
</OutOfBrowserSettings.SecuritySettings>
Visual Studio 2010 Beta 2 now has support for setting this value in the OOB properties dialog.

Detecting Full Trust Status
In the Silverlight application code, you can detect if you’re running full trust by inspecting a property on the Application object.
if ( !Application.Current.IsRunningOutOfBrowser )
{
MessageBox.Show( "You are not running OOB" );
return;
}
else if ( !Application.Current.HasElevatedPermissions )
{
MessageBox.Show( "You are not running in Full Trust" );
return;
}
Now What Can I Do ?
One of the things we did for the keynote demo is to integrate the app with Microsoft Office. We create Excel spreadsheets, Word documents, Outlook meeting request, even check the Outlook calendar for available meeting times. There is no built-in support for Office in the Silverlight class library, so you have to resort to COM to talk to Office. Use the ComAutomationFactory.CreateObject() method to create a COM object from its ProgID, and you’re off and running. From there, it’s just working through the Office object model.
dynamic excel = ComAutomationFactory.CreateObject( "Excel.Application" );
excel.Visible = true;
dynamic workbook = excel.workbooks;
workbook.Add();
dynamic sheet = excel.ActiveSheet;
// create some headers and some data
for ( int i = 0; i < 3; i++ )
{
dynamic cell = sheet.Cells[1, i];
cell.Value = String.Format( "Column {0}", col );
cell.Font.Bold = true;
}
// create some sample data (obviously, you can pull from whatever
// datasource you have to fill this in with good data)
for ( int row = 2; row < 10; row++ )
{
for ( int col = 0; col < 3; i++ )
{
dynamic cell = sheet.Cells[row, col];
cell.Value = String.Format( "Row {0}, Col {1}", row, col );
}
}
sheet.Columns.AutoFit();
Marshal.ReleaseComObject( excel );
What Else?
With full trust, it’s almost unlimited what you can do from the Silverlight client code (local devices like cameras, scanners, bi-directional communication with COM objects, etc).
Party on!
… when you’re in OutOfBrowser mode and you don’t yet have RootVisual set to something. Let me explain.
Early this week I was struggling with a Silverlight app that would work just fine when running IN-browser, but then when run OUT-of-browser (OOB) it would never show the initial content. After lots and lots of debugging and trial and error, I found that the first WCF service call was never returning (never calling it’s Completed event handler).
In the simplified code below, notice that we are calling a WCF service (asynchronously, as all service calls in Silverlight are done) and doing some follow-up work in the Completed handler, including setting the RootVisual.
private void Application_Startup( object sender, StartupEventArgs e )
{
SomeServiceClient svc = new SomeServiceClient();
svc.AddCompleted += delegate( object sender2, AddCompletedEventArgs e2 )
{
MessageBox.Show( e2.Result.ToString() );
RootVisual = new MainPage();
};
svc.DoSomeWork( 2, 3 );
}
In this case, when running OOB, the service will never return, and therefore never call the completed event. In fact, I think it never actually makes the outbound call. I had breakpoints over in the service implementation that would not get hit. No exception, nothing. Not even break on all exceptions would show anything.
The only thing I can come up with is that it has something to do with dispatching messages through the message pump to get the WCF call working. When there is no RootVisual, there is no UI (no dispatcher) to help with that. When running IN-browser, we must be leaning on the browser UI thread that’s already pumping messages.
So the fix is as simple as making sure RootVisual is set to something before the first WCF call. We have a case where we don't know what content to show until we get back from the first service call, so I show an empty Panel, and then add the content in the service Completed handler.
private void Application_Startup( object sender, StartupEventArgs e )
{
RootVisual = new Grid();
SomeServiceClient svc = new SomeServiceClient();
svc.AddCompleted += delegate( object sender2, AddCompletedEventArgs e2 )
{
MessageBox.Show( e2.Result.ToString() );
var panel = RootVisual as Panel;
panel.Children.Add( new MainPage() );
};
svc.DoSomeWork( 2, 3 );
}
I made a couple of improvements to the WPF Snoop utility that I posted a while ago. (as before, this is an update to the original created and posted by Peter Blois, with his permission)
Property Filter ComboBox info now comes from config
After publishing the last version with property filter support, I continue to get suggestions from people using the tool for other properties and groups that should be included. This is obviously begging for the data to be based on configuration, so I dove in and made it so.
It’s not as straight forward as a simple app.config setting, since the code that displays the property grid and needs to know about those property filter groups is running within the process space of the EXE that you’re snooping. So you still edit the config file that’s in the directory where have snoop.exe installed, but at runtime, the config is read “remotely” from the snooped EXE.
To add/edit property filters, edit snoop.exe.config. The layout looks like this:
<PropertyFilters>
<add DisplayName="Layout" PropertyNames = "width,height,actual,margin,padding,canvas,align" />
<add DisplayName="Grid/Dock" PropertyNames = "grid,dock" />
<add DisplayName="Color" PropertyNames = "color,background,foreground,borderbrush,fill,stroke" />
<add DisplayName="ItemsControl" PropertyNames = "items,selected" />
<add DisplayName="Text" PropertyNames = "font,align,trim,wrap" />
</PropertyFilters>
The comma-separated values in the PropertyNames attribute are split and used as case-insensitive substring searches.
Mouse Wheel Property Editing
I just finished a WPF project where we used Visual Studio 2010, and it required lots of WPF canvas layout. Normally I would fire up Expression Blend to lay things out exactly where I want them, and be done. Unfortunately, Blend 3 does not (yet) like VS 2010 project files. So this made for a very tedious couple months of run-time adjustments of elements. I would run the app, and use Snoop to adjust Canvas.Left/Top, Margin, Width/Height, etc, each time, typing in a new value, seeing the changes in the app. UGH.
So that was the motivation for this new feature. Now when you select a property in the property grid, for fields that support discrete changes to their values, you will see an additional copy of the current value in the right edge of the current value column. The great thing about this copy of the property’s value is that you can mouse wheel over them to CHANGE THE PROPERTY VALUE!
There are many data types supported: the obvious int, double, and boolean; and then maybe not so obvious. Data types supported:
(For the above numeric types, the default is to change the value by 1. Hold down SHIFT while wheeling to change by 10, hold down CTRL while wheeling to change by 0.1)
- Boolean
- Thickness
- Brush
- Visibility
- Horizontal/VerticalAlignment
For the “multi-part” data types (Thickness and Brush), you can change individual parts of the property by mouse-wheeling over just that part.
So this ends up giving me a run-time design experience where I can quickly tweak layout and style without a bunch of text typing / editing.
(Thanks to my co-worker Brad, who tested this version and blew it up when trying to mouse-wheel edit a LinearGradientBrush background. Types that derive from supported types (i.e. GradientBrush from Brush) that are not supported are listed in the config file and can not be edited with the mouse wheel. In the case of GradientBrush, you CAN delve into the GradientBrush, to the GradientStops, use the Indexer feature added last time, and then adjust the color or offset of an individual stop at runtime!!)
The Bits
The binaries – one folder for 32-bit and one for 64-bit.
The source code for the solution.
Give it a try! Hope you like it.
The popular Snoop tool from Peter Blois has been out for a long time, and I use it almost every day in my WPF development. However, there has always been something missing: a native 64-bit version.
My coworker Joe and I finally decided that it was worth looking into building one. There were a few tweaks to the code itself to compile in 64-bit, and then some project build directory settings changes … but for the most part, it was pretty straight forward to make.
So with permission from Peter Blois, I have created and posted a true 64-bit version of Snoop. Mind you, this is version 1 of Snoop – haven’t yet tried to tackle version 2. I tend to use v1 in my everyday WPF dev – not having property editing in v2 is a showstopper for me.
Bit Versions
Snoop works its magic by injecting a DLL into the process space of the app you are snooping. The problem with snooping a 64-bit app with the original snoop is that the injector DLL was always 32-bit, and when Snoop tries to load a 32-bit DLL into the 64-bit target application, you get the invalid image exception.
To allow snooping either a native 32 or 64-bit target app, I have built both a 32 and 64-bit version of Snoop and its supporting ManagedInjector DLL. So unfortunately, the only downside of this approach is that you have to keep both versions around, and use the one that’s right for the bit-level of the target app. (There has already been a request for ONE version of Snoop that will load the appropriate version of the injector DLL, so maybe someday I’ll dig deeper into that.)
Enhancements
While I was in there building Snoop, I decided to throw in a couple other tidbits - either changes to small things that have always bugged me, or small features that I wish the original had.
- “ShowAllProperites” ToggleButton is off by default. I find that more times than not, the properties I want to look at are in the “defaults” set, so this keeps the properties list much shorter.
- Use a 2nd monitor if present. My everyday use of Snoop is that I choose the app to snoop, the SnoopUI comes up and I move it over to my 2nd monitor. I added some code to do this automatically if there’s a 2nd monitor present.
- Scroll to Selection – when you snoop on an element in your app with CTRL+SHIFT pressed and the element is found in the tree, the selected item is automatically scrolled into view.
- Custom property filter ComboBox.
In addition to filtering the properties list by text, there is now a ComboBox next it that allows to filter the properties by functionality. For example, if you choose “Layout”, you see only properties like Width, Height, Margin, etc. that have to do with layout. Choose ItemsControl for things like ItemsSource, SelectedItem, etc. This screenshot shows snooping on a ListBox with the custom property filter set to ItemsControl to quickly see everything related to ItemsControls and Selectors.
- Indexer delve. This is the small TextBox to the right of the Custom Property ComboBox. If the current property type (that you’ve delved into) is an ICollection, you can type an index value in the TextBox and delve into that item in the collection. The indexer delve plays along with all the other delves, so you can pop context to get back to where you came from.
Here is the properties window after delving into a collection data type (ListBox.ItemsSource which is ObservableCollection<Person> in this case).
After entering a “1” in the Indexer Delve field (updates on text change), you see the Person object at index 1 in the above list.
There you have it. I hope these enhancements, along with a native 64-bit version are helpful in your WPF development!
Here is the zip with both 32-bit and 64-bit folders. And since the original source was posted, here is the source code for this updated version.
By now you've probably at least heard of Microsoft's "Live Mesh" - a virtual network of your platform-agnostic devices (computers, phones, PDAs, etc) that all sync with the same data via the internet. Live Mesh is part of Microsoft's larger "Azure Services Platform" which is their version of "the cloud", providing internet-scale services hosted at MS data centers.
At PDC this past year, Microsoft released the first tech preview of the Live Framework (one of 4 pieces of the larger Azure Services platform) which allows you to write code against the Live Mesh, enabling you to read and write data to the mesh itself, and write apps that are aware of the mesh data, and take advantage of its inherent synchronization, making data available to all the devices in your mesh, without you writing a single line of synchronization code!
There are a couple different approaches to writing an app that talks to the mesh, the most compelling of which I think is the "Live Framework Silverlight Mesh-enabled Web Application". Whew - that's a long winded way to say the following: Write a Silverlight control that would normally be hosted in a normal browser, but that is instead registered as a "Mesh application", that can then be run via the Live Mesh Apps portal (part of the Live Mesh Desktop)
Here is a screenshot of my browser sitting on the Apps page, showing me the Silverlight Mesh-enabled web apps that I have installed.
These "applications" have been installed in my Mesh and are ready to run. (The Collaborative Crossword is one that is published by MS for anyone to use. The other 2 are apps that I have published when playing with the Live Framework SDK.)
So now hopefully you can see the power of these Mesh apps that can run on any device that can show Silverlight content. Create apps that store their data in the Mesh and you automatically have a network/synchronization aware app. When you create one of these Silverlight Mesh-enabled web apps, the project is already setup to communicate directly with the mesh.
public Page()
{
InitializeComponent();
// Extension method to get a hold of the MeshApplicationService
_meshApp = Application.Current.GetMeshApplicationService();
// once mesh contents are loaded we get callback and we're ready to party
_meshApp.LoadCompleted += new EventHandler( meshAppLoaded );
_meshApp.Load();
}
// Called when mesh application loads
void meshAppLoaded( object sender, EventArgs e )
{
// Mesh application service object is now loaded and usable.
Mesh mesh = LiveOperatingEnvironment endpoint = meshApp.LiveOperatingEnvironment;
// do something with the data objects you've stored in the mesh for this app
foreach (MeshObject mo in mesh.MeshObjects.Entries)
{
string title = mo.Resource.Title;
// ...
}
}
In the code above, you are given the MeshApplicationService, from which you can get the Mesh object, and iterate over objects stored in there, add new objects, etc. (Someday I'll write more about exactly how you read/write objects).
OK - so now the super powerful part: When you register/install the application in your Live Mesh Apps workspace, you also get an icon on your Windows Desktop that represents the same app, only it runs the Silverlight control in a local shell application and communicates with a local instance of the mesh running on your machine!
So this icon on your Windows desktop runs the Silverlight content in a shell app running in Windows called "MeshAppHost.exe" with a parameter to tell it what app to run (the apps themselves are stored in the mesh as well, so this shell just retrieves the Silverlight bits and runs them).
The coolest thing about this local running shell app, is that it is communicating ONLY with the local instance of the Mesh running on your machine, and is therefore fully functional while YOU ARE OFFLINE! Since your app presumably updates data in the mesh, those are done locally, and then whenever you are back online, the mesh runtime will sync the changes up to the internet mesh and over to whatever devices are registered.
So there you have it! Not only Silverlight running outside of a browser on the local machine, but reading/writing data via the mesh while offline that gets sync'd whenever you are back online.
A couple notes about when you're running offline:
- At some point before you try to run offline, you must have successfully logged into the Mesh (via the system tray / login tool) and be sure to select "Remember me" and "Remember my password". Your credentials are then cached in the locally running mesh to authenticate when you're offline.
- So far, I have only found one difference in the way you have to access objects in the mesh when offline. Instead of loading objects "on demand" when you ask for them, you need to explicitly load them:
// if offline, the for-loop below will not work unless you
// explicitly Load() them first
mesh.MeshObjects.Load();
foreach (MeshObject mo in mesh.MeshObjects.Entries)
{
// ...
}
If you need to know in the code if you are connected locally or online, you can use this:
meshApp.LiveOperatingEnvironment.IsLocalConnection
Have fun writing multi-device, multi-platform synchronization aware, offline capable apps -- as simple as writing a Silverlight control.
p.s. To get started writing these Mesh-enabled apps, you need to download the Live Framework SDK. MS is slowly allowing more and more devs access to the SDK. Start here and request a token which they'll send you in email. (When registering, be sure to specify the "Live Framework" API in the ComboBox about what you're interested in.)
We have all been using interfaces in .NET and even before that to maintain loose coupling between objects. These days this is most often done for things like a data provider layer, a plug-in model where assemblies are loaded at run-time, and various other "behind the UI" areas of functionality. The idea behind using interfaces is to allow us to program against the interface and not the object class itself, so that the object class can be swapped out for another one that implements that interface and the caller never knows.
I have been working on a rapid UI prototyping effort for the past couple years and we have taken this use of interfaces to the UI layer, where I don't see them used much, to allow us to remain very de-coupled amongst the various pieces of UI.
If you're developing WPF apps, you have most likely heard of the Model-View-ViewModel pattern, whereby the ViewModel is the DataContext for the View and it's job is to transform and store the Model data in such a way to allow easy data binding from the View. Typically you have a different VM for each view and even for "sub-views" or even items in a list, so hooking them all together gets complicated. We have added the use of C# interfaces to these ViewModels to keep us from coupling them all together where they're rely on their relative position to each other, allowing us to quickly and easily move things around. Many times in rapid prototyping, the requests come streaming in: "move this over there, change this list to a toolbar, make this other thing a menu, get rid of that thing and replace it with this thing" ...
If you have all these "widgets" (ViewModels) in the UI tied together with binding statements or other tightly coupling coding practices, you will be doing LOTS of refactoring when these requests come in.
We chose to represent the logical chunks of functionality found in the ViewModels as interfaces and hook ViewModels up by passing interfaces around. This way, if a request comes in to move/replace/change the look or placement of the view, as long as you replace it with one that either talks to the same ViewModel, or minimally a new ViewModel that implements the same interface as the one you're replacing, no other code has to change.
Let's go through a simple example to illustrate what I'm talking about.
I threw together a pretty standard Master-Detail type of UI, one that shows Super Bowl players on the left, and shows details about the selected one on the right.
You could certainly write this as a simple WPF app with all XAML based Binding statements using ElementName bindings to each other, but then when the request comes across your desk to move the ListBox area to a Menu or a completely different view in a popup or some such, you'll be bumming on the XAML bindings idea.
Instead, we're going to implement the 2 different pieces of the app (master and detail) as two different ViewModels, and the one that handles selection of a player will do so as an interface.
We create a ViewModel called PlayerListVM for the player selection area (ListBox) that backs the UI area that holds the ListBox.
When looking at its main duty as the ViewModel for player selection (tracking the currently selected player), we can express that in an interface called IPlayerSelection.
// PlayerListVM.cs
interface IPlayerSelector
{
Player CurrentPlayer { get; }
event EventHandler PlayerChanged;
}
class PlayerListVM : IPlayerSelector, INotifyPropertyChanged
{
...
private Player _currentPlayer;
public Player CurrentPlayer
{
get { return _currentPlayer; }
set
{
if ( value != _currentPlayer )
{
_currentPlayer = value;
OnPropertyChanged( "CurrentPlayer" );
}
}
}
}
Now when we create the Details view, we feed the IPlayerSelector interface to the PlayerDetailsVM, and then expose the interface as a public property of the ViewModel so the View can bind to it in XAML.
// PlayerDetailsVM.cs
public PlayerDetailsVM( IPlayerSelector playerSelector )
{
PlayerSelector = playerSelector;
}
private IPlayerSelector _playerSelector;
public IPlayerSelector PlayerSelector
{
get { return _playerSelector; }
set
{
if ( value != _playerSelector )
{
_playerSelector = value;
OnPropertyChanged( "PlayerSelector" );
}
}
}
As you can see, we do this via a constructor argument. The code that creates the ViewModels creates the PlayerListVM, and when creating the PlayerDetailsVM, it passes the IPlayerSelector interface (the PlayerListVM) in the constructor. The bottom line is that the PlayerDetailsVM has a dependency on the IPlayerSelector interface, which needs to be set for the VM (and its view) to work correctly.
PlayerListVM playerListVM = new PlayerListVM();
DataContext = playerListVM;
PlayerDetails details = new PlayerDetails();
details.DataContext = new PlayerDetailsVM( playerListVM );
OK - so you Blend people out there (or even those that like to construct and wire up the DataContext of a View to its ViewModel in XAML) are now saying, "but wait, I don't want this code-based dependency injection!".
Easy enough if you use an Inversion of Control (IOC) container to resolve dependencies for you. Here's how I did it with Microsoft's Unity framework:
// App startup ...
PlayerListVM playerListVM = new PlayerListVM();
DataContext = playerListVM;
// Register this interface in the IOC container for others to use
App.IOC.RegisterInstance<IPlayerSelector>( playerListVM );
// -- PlayerDetailsVM.cs --
public PlayerDetailsVM() // now it's a no-arg ctor
{
// use IOC container to resolve dependency
PlayerSelector = App.IOC.Resolve<IPlayerSelector>();
}
// -- PlayerDetails.xaml --
// you can also setup the DataContext in XAML now
<UserControl ...>
<UserControl.DataContext>
<viewModel:PlayerDetailsVM />
</UserControl.DataContext>
</UserControl>
You get rid of the constructor-based dependency on the PlayerDetailsVM class and it resolves its dependency on IPlayerSelector on its own. (and you can even do the ViewModel construction and binding in the View's XAML)
So now your XAML for the details view goes from tightly bound ElementName-based bindings to much more loosely coupled interface-based bindings like this:
<!-- PlayerDetails.xaml -->
<!-- tightly bound XAML, based -->
<!--
<TextBlock Text="{Binding SelectedItem.Team, ElementName=PlayerList}" />
-->
<!-- Access the CurrentPlayer via the interface, stored in the VM -->
<TextBlock Text="{Binding PlayerSelector.CurrentPlayer.Team}" />
Admittedly, all this is definitely overkill for a simple master-detail app like I'm showing. It has worked very well though for our UI that has over 10 ViewModels all playing together at the same time, and on more than one occasion had to be moved, changed, or replaced.
Hope that's helpful.
Here is a zip of the sample project that shows the loosely coupled ViewModels.
I have been using Firefox keywords with string substitution since FF version 2 and am amazed at the small number of my friends and coworkers know about and use them. What the heck am I talking about? Keep reading...
Everyone knows how to save a URL as a favorite - every browser does it. But not every browser offers the ability to assign a "keyword" to that URL. This is a user-defined symbolic name to represent whatever URL you're saving in the bookmark. It's like shrinkster, tinyurl, etc. for your local browser. Once defined, type the couple characters into the Firefox address bar and you'll be whisked off to the full URL.
g = http://www.google.com
traf = http://www.dot.ca.gov/dist11/d11tmc/sdmap/showmap.html
azure = https://lx.azure.microsoft.com/Cloud/Provisioning/Default.aspx
... etc ...
"No bid deal" you're saying? It definitely saves keystrokes, but here's where the magic happens. String substitution allows you to build up the URL with a placeholder, where anything you type in the address bar after the keyword gets stuffed into the URL. This is probably most often used for search forms, where you save the time of hitting the search form, then typing in the search terms, then hit GO.
gm = http://maps.google.com/maps?q=%s
"gm carlsbad" = %s replaced with "carlsbad" to get a google map look up on carlsbad
wu = http://www.weatherunderground.com/cgi-bin/findweather/getForecast?query=%s
"wu carlsbad" = %s replaced with carlsbad to get weather lookup on carlsbad
wp = http://en.wikipedia.org/wiki/Special:Search?search=%s
"wp superbowl" = lookup "superbowl" on wikipedia
del = http://del.icio.us/volleynerd/%s
"del azure" = finds me my delicious bookmarks for a given tag
My favorite by far for everyday development: I built the URL for a google "site-specific" query against microsoft.com to find a .NET class name, method, property, etc. Almost guaranteed to find me the MSDN SDK topic I'm looking for in the top 3 results.
gms = http://www.google.com/search?biw=1263&hl=en&q=site%3Amicrosoft.com+%s
"gms window class" from the address bar immediately finds me the MSDN docs on the .NET Window class
Now that you're (hopefully) sold - it's super easy to create these shortcuts with keywords and string substitution.

- Go to the site or perform a search like you would "in the old days"
- Create a bookmark for the results like you would for any other page
- Edit the bookmark and tweak the URL - replace the search term you entered with a %s
- In Firefox 3, hit the "More" button to see the keyword field
- Enter your desired keyword
These are just regular old "favorites" in Firefox's mind, so they'll sync to multiple machines if you're using something like Foxmarks.
Enjoy the shortcuts!
Comments: if you're using Firefox shortcuts with keywords and string substitution - leave me a comment with some of your favorites.
I have only recently started using Silverlight, but immediately found the much talked-about issues related to cross-domain network calls. The security layer baked into the Silverlight runtime prevents calls from the client to any remote server that is different from the one where the XAP file came from in the first place. Calls to other servers WILL succeed only if there is a clientaccesspolicy.xml or crossdomain.xml file on the remote server. (Either of these files establish a policy for that server to allow calls from a set of configurable domains.)
For my first stab at a Silverlight client, I started writing an RSS reader - with WPF/Silverlight standard binding to XML, should be pretty easy right? That is - if you can get the RSS/Atom XML in the first place.
Popular sites that serve RSS or Atom seem to have the cross-domain XML files in place, but I found a handful that did not, so I didn't want to bank on it. Code like the line below throw a "Security Error" exception.
client.DownloadStringAsync( new Uri( rssUrl ) );
Enter: the "pass through" service layer.
Conceptually, I need a service method residing in the same web site that my Silverlight pages come from. I want to call a service method, passing it the "real" url that I want to go to for the RSS/Atom, and have this custom service go get the requested XML for me, and return it. I'd like this to be transparent to the Silverlight client - it should get the exact same response data that it would if it could call the remote server directly (i.e. if it had a cross domain policy file). This can turn out to be a generic pass-through service for any content the Silverlight client needs from the web (ASP(x) pages, XML, REST calls, etc).
I started with thoughts about using WCF, then REST which allows me to use url parameters and would make for an easy WebClient call from the Silverlight client code. However, even the REST idea is still using WCF, which always returns serialized DataContract objects to the client.
Even the simple WCF REST method below:
[OperationContract]
[WebGet( UriTemplate = "PassThru?url={url}" )]
public string SilverlightPassThrough( string url )
{
WebClient client = new WebClient();
var bytes = client.DownloadData( url );
string response = Encoding.ASCII.GetString( bytes );
return response;
}
...will return the XML from the requested URL, but it will be wrapped in a <string> element since WCF will serialize the string result.
<string xmlns=...>
<rss version="2.0" ...><channel><title> ...
</string>
Finally, I went way back to the ASP.NET roots, and decided to use a simple .ASPX page, where I can squirt the XML I get from the remote server, directly into the response stream, and the client won't have any idea.
I created a basic .ASPX page in the same web site as my Silverlight page, cleared out all HTML markup in the ASPX file,
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GetRssFeed.aspx.cs"
Inherits="PodSync.Web.GetRssFeed" %>
<!-- no more markup here (would start the Response stream before we have a chance to -->
and then added the following code:
protected void Page_Load( object sender, EventArgs e )
{
WebClient client = new WebClient();
var bytes = client.DownloadData( url );
string response = Encoding.ASCII.GetString( bytes );
// if remote server gave us a Content-Type, return it to our client
string contentType = client.ResponseHeaders["Content-Type"];
if ( !String.IsNullOrEmpty( contentType ) )
{
Response.ContentType = contentType;
}
Response.Write( response );
}
Now my Silverlight client just makes a call like this:
string origUrl = Feeds.SelectedItem.ToString();
string escapedUrl = origUrl.Replace( "&", "%26" );
string url = String.Format( "/GetRssFeed.aspx?url={0}", escapedUrl );
_client.DownloadStringAsync( new Uri( url, UriKind.Relative ) );
//TODO: parse the response XML in the DownloadStringCompleted handler
...
(Notice the escaping of & in the URL we send to our Pass-Through page. If we dont escape those characters, they are viewed by first class parameters to the GetRssFeed.aspx page, and not part of the requested URL.
Like I said, I can use this same page for any "content" based pages that my reader needs - including the plain content pages for a given RSS item.
Super simple solution I know, and uses "old school" technology, but seems to satisfy my requirement of feeding back the same exact page as you would get if you could call the remote server directly from the Silverlight client.
Hope that helps.
My co-worker Kevin Kennedy (surface/graphics/3D expert) and I recorded a podcast for .NET Rocks, which hit the streets a couple days ago. We talk about developing for the surface, loosely coupled WPF apps, everyday WPF life with VS 2008 and Blend, RECESS, and a few other topics.
There's even an announcement about how/where you can get the Surface SDK bits, without buying a Surface table!
Check it out here!
I have been using LINQ for a while now for pretty standard queryies, usually against object collections. One of the extension methods in the System.Linq.Enumerable class that I find I'm using more and more is the SelectMany( ) method - it wasn't obvious at all to me when I first saw it what it's purpose is.
This is best illustrated by an example. Suppose I have defined some classes that represent a League that contains Teams and Teams contain Players. This is a fairly typical hierarchical collection of objects that I work with every day. In this example, I want to find all the Players across all Leagues and Teams that meet some certain criteria. The "poor man's" way to do this is use for-loops walk through each League, then each Team and collect the Players that I'm looking for. Well, this is exactly what SelectMany( ) can do for us.
My collection of Leagues, Teams, and Players has a structure like the following:
- League: AFC-West
- Team: Chargers
- Player: Rivers
- Player: Tomlinson
- Player: Gates
- Team: Broncos
- Player: Cutler
- Player: Bailey
- Player: Marshall
- League: AFC-South
- Team: Colts
- Player: Manning
- Player: Addai
- Player: Vinatieri
Now let's write some queries (I use LINQPad to play with these queries and get immediate feedback/output).
This most basic version gives you a flat collection of IEnumerable<Team> of all the teams in across all leagues.
var allTeams = from t in leagues.SelectMany( l => l.Teams )
select t;
You can chain the SelectMany calls together to dive as deep as you want in the hierarchy. This returns an IEnumerable<Player> of all players in all leagues & teams.
var allPlayers = from p in leagues.SelectMany( l => l.Teams ).SelectMany( t => t.Players )
select p;
And of course you can add where clause criteria to further refine which players you get now that you're operating on the flat list of players.
var onlyYoungPlayers = from p in leagues.SelectMany( l => l.Teams ).SelectMany( t => t.Players )
where p.Age < 30
select p;
Here's a good way to chain Where( ) in between the SelectMany( ) calls get all the players only from certain teams.
var players = leagues.SelectMany( l => l.Teams )
.Where( t => t.NumberOfWins > 2 )
.SelectMany( t => t.Players )
.Where( p => p.HomeState == "CA" )
.Select( p => p );
The 3rd and 4th overloads of the SelectMany( ) method with the additional "result selector" parameter take a bit more explanation. I look this extra result selector parameter as a helper object to help you know the relationship between the parent and child collections. Say you need a result collection that will not only have the full list of Teams that match some criteria in all leagues, but need to know what League the teams are in. If you use one of the above queries, you get the flat list of Team objects, but have lost their connection to what League they're from. (Sometimes you have "back references" in your object model to get from a child object to their parent, which makes using this result selector unnecessary, but you don't always have that benefit.) The result selector is an intermediate object availble within the scope of the query to give you the information you need, and it's up to you to decide what data you need in the result selector to help you. Here's an example:
var teamsAndTheirLeagues = from helper in leagues.SelectMany( l => l.Teams, ( league, team ) => new { league, team } )
where helper.team.Players.Count > 2 && helper.league.Teams.Count < 10
select new { LeagueID = helper.league.ID, Team = helper.team };
So the helper object is created from the 2-argument Func<> which takes the object from the parent collection and the object from the child collection that are getting paired up during the query processing, and you can do whatever you want with them - I'm just doing something easy that creates a new anonymous type with those objects embedded in them, which gives me the ability to use that data in the where clause, as well as in the results of the query. (Note: you can just "select" the whole helper object in the final line of the query as well)