we currently have a (quite large) WPF code base that we are successfully reusing (by compile switching where needed) for Silverlight and WP7 versions of the same app. This is all good and works fine, and of course will be the path to bring our app to Metro (the pieces that make sense anyway).
The real issue though is with XAML: there are differences between WPF and SL (and of course differences now with Metro XAML). We have been able to workaround some of these differences by using slightly different constructs but sometimes it is just not possible, and we end up having a duplicate XAML file for SL where 99% of the file is the same and one tiny little attribute is different - which kills maintainability (have to remember to update all the versions of the same file).
Would it be possible to add some special construct (a new comment type or something) to XAML in order to achieve "compiler-switch" functionality? This way it would be much easier for users targeting multiple platforms (WPF, SL, Metro, WP7) to reuse their existing assets.
I'm currently working on a blog series on how to accomplish this starting here: http://www.sharpgis.net/post/2011/09/15/WinRT-vs-Silverlight-Part-0.aspx
My worry is the opposite of yours. For the XAML case I haven't found much difference other than the why you declare xml namespaces. This of course does mean you will be having a copy of your xaml and have to maintain both copies since we don't have if-defs in XAML. It could be accomplished through a little build task as well to automate this process though. At least the change here is straightforward and the rest of your xaml carries over.
For the code portion however, I see a much larger problem. I've been cross-compiling sourcecode for WPF, Silverlight and WP7 for quite some time now with pretty good success. So like you I thought I could just continue down that road for WinRT. However the more I work on this, the more I realize that that is probably not a very good idea. First of all there's a lot of syntax changes, so you will need a lot of compiler directives, almost to a point where it gets unreadable. Next is that the new API's are very focused towards the new async pattern, and you will have to have your code match that. That means your code flow will be very different in the different versions. At the very least you will have to write quite a lot of abstraction logic that is going to affect all your build targets if you want maintanability. I know some of these things are going to get a little better as we move toward a solid beta, but the async pattern alone forces quite some changes on to your code.
Has anyone considered creating a XAML code generator that would take a source platform agnostic XAML file and "generate" a platform specifc one that would then be compiled? Auto searching and replacing for the namespace differences and other minor differences should not be too hard. From my very limited knowledge of T4 Design-Templates this seems like something that would be easily accomplishable.
I realize that this would most likely prevent the interactive designers from working but I would rather that then duplicating all of the XAML files multiple times.
I recently blogged about a way to use ObservableCollection with WinRT, using a value converter to adapt the ObservableCollection to a IObservableVector interface, which the WinRT XAML UI requires:
Here is what I do. I moved my code that is unique to WinRT or Silverlight to XAML code behind. Platform specific code is wrapped in preprocessor statements. For differences in XAML namespace declarations I wrote a utility to switch namespaces back and forth between Silverlight and WinRT conventions. There is a feature in Visual Studio to run external commands (Tools -> External Tools). So I have one command called "make Silverlight" which replaces "using:" with "clr-namespace" and another called "make WinRT" with the reverse option.
I use a Silverlight application for the web as my base project for all files and the WinRT project references these XAML and CS files as external links. Through this approach I am able to share source between Silverlight and WinRT. I can't dual compile simultaneously, but using the aforementioned external command, I can compile each project individually with relative ease.
If you are building a business application the above approach may not be sensible because it can be challenging to work within 'Metro' design principles without using WinRT libraries. But if you are building a game or your WPF/Silverlight app shares Metro design principles, this option may work for you.
- 編集済み S Tonstad 2012年12月26日 20:23
If the only thing you are after is to be able to use the "using" syntax for namespace declarations, the solution is very simple.
Add the following attribute to the Silverlight assembly
[assembly: XmlnsDefinition("using:PlaybackManager", "PlaybackManager")]
to be able to use the "using:" namespace in Silverlight XAML.
I was working on porting my WP7 app to Windows 8 and discovered this today. Hope you find this useful!
Hi Louri. I was hopeful and I gave your approach a try. It seems to work fine for external assemblies but for controls referenced within an assembly, I get "The name [insert class name here] does not exist in namespace [using:myNamespace]. So if my assembly is Foo, I cannot use XmlnsDefinition within Foo to reference classes contained within Foo. I am thinking that your approach may not work for large projects. It's a shame, because it would be a succinct solution.
I have only ever used it for classes inside the same assembly. I spent some time to try and found out why I missed the issue.
I used Windows Store application project to design the control - that works fine. At runtime, both projects work fine. At designtime, however, the Silverlight (Windows Phone in my case) project's designer is broken with the error you describe.
This was a workable trade-off for me, but may not suit others. The workaround is to move classes referenced from XAML into a separate assembly for SL/Windows Phone projects, but it's not worth the hassle for me.
- 編集済み Iouri Simernitski - MSFT 2012年12月31日 20:17