I am writing code that is used in both WPF and Silverlight. In C# I can use "#if SILVERLIGHT" for conditional compilation, and it works.
In XAML, however, I must resort to use completely different XAML files, since some attributes are simply incompatible. XAML files are 99% a like, and keeping them in sync is a hassle.
I would like to convert them into a T4 template, so I can do things like:
<SomeControl <#=ClipsToBounds()#> />
Where ClipsToBounds() produces different text for WPF and Silverlight. The requirements are:
Intellisense while working on the XAML
Templates generated at build time
The project must be self contained and work on stock version of Visual Studio: installs of various SDKs and 3rd party editors are not
acceptable
Results of the template run should NOT be in source control. -
I found that I can change custom tool on a XAML file from MSBuild:Compile to TextTemplatingFileGenerator and I don't lose Intellisense. However, resulting templates are generated at design time. To have then generated at build time seems like a big pain.
Did anyone have successful experience with this kind of setup?
Only the generic user controls which have generic behaviors across the platforms can be placed in PCL , However,the best suggestion would be keeping separate xaml views for each platform .
Since nobody seems to have suggested a template based solution as desired, I'll share some experience of working with projects targetting both SL/WPF. Many people will suggest using two completely separate XAML files, a different view per-platform, and in many ways this is the "purist" thing to do. But if you want to eliminate duplication, and reduce the risk of your 2 targets drifting apart, I'd certainly suggest sharing the XAML files (with simple project links) can work acceptably well.
There are a few common incompatibilities:
Controls exist in both platforms in different namespaces - subclass your own version and refer to that.
Styles etc. need differ between platforms - include a common dictionary of resources, different per platform, and reference by key.
Controls are substantially different, or present in only 1 platform - introduce your own wrapper control (which may require substantial implementation in the 'missing' case).
Basic properties or functonality missing - can often hack something up with an attached behaviour (eg your ClipsToBounds example is found here).
Related
Hi this might seem like a dumb question, but I was looking for a little feedback. I am designer working with a development team on a WPF application. We installed Expression Blend 4. I new to WPF/Silverlight, but I have jumped right in and I think it's great.
However, I did notice that xaml code that can get generated when using Expression Blend can sometimes be overly obnoxious. For example, I created a Control Template for a button with Blend and the markup was like 100 lines of code. Then I created my own control template that was only 20 lines or so and it did exactly the same thing. I did the same thing for a listview and wow, that amount of code that was generated for a ListView template was RIDICULOUS. So again, I created my own styles and templates and the result was A LOT less xaml code.
The app we are creating is going to be pretty big I guess, so my question is, is it that much of a concern for performance if I were to simply create all design/interface elements using blend GUI, even though the generated code can be a lot more extensive? I can see how using Blend tools for design can make things a lot easier, but just like when designing websites, I have never used design view in Dreamweaver because the code that gets generated is pure crap.
Any insight would be greatly appreciated.
Thanks a lot
Personally i would only use any designer for drafting and real-time display of the visual representation of my hand-written code. The generated code may not be horrible but once you need to go into it to do something manually you will have a hard time finding everything you need if you did not write it yourself. Also Blend slices things up quite a lot (create resource & reference it) while i like to nest things in place if they are only used once (i do not know if the code generator could be adjusted in that regard).
It should not be performace concern that the templates are big, if you just copy the default ones used they are quite huge themselves and it's not really an issue.
I'm guessing the control template you generated for the button didn't actually do the exact same thing as the default one which you copied in Blend. You may think it did, but I'm guessing it was missing something. For example, did your template handle all 9 visual states that are used by a button? If you had only 20 lines of XAML, probably not. And yes, the ListView control template is quite large because it's quite a complicated control under the covers.
In general, I wouldn't worry about generating large control templates. It's going to happen. The runtime handles this quite well, in general. Unlike Dreamweaver, Blend generally gives you pretty good code. Performance only becomes an issue if you misuse resource dictionaries by doing something ill-advised such as setting the build action to embedded resource in visual studio. (I believe this creates a loose XAML file which must be parsed and compiled at runtime instead of compile time.)
The key to maintaining your sanity is organization. Just like with a website, you need to come up with an organization scheme for how you're going to store your control templates.
A while ago, I posted a question regarding switching between a Blend-authored GUI and a Visual Studio-authored one. I got it to work okay by adding my Blend project to my VS2008 project and then changing the Startup Application and recompiling. This would result in two applications that had completely different GUIs, yet used the exact same ViewModel and Model code. I was pretty happy with that.
Now that I've learned about the Laurent Bugnion's MVVM Light Toolkit, I would really like to leverage his efforts to make this process of supporting multiple GUIs for the same backend code possible. The question is, does the toolkit facilate this, or am I stuck doing it my previous way?
I've watched his video from MIX10 and have read some of the articles about it online. However, I've yet to see something that indicates that there is a clean way to allow a user to either dynamically switch GUIs on the fly by loading a different DLL. There are MVVM templates for VS2008 and Blend 3, but am I supposed to create both types of projects for my application and then reference specific files from my VS2008 solution?
UPDATE
I re-read some information on Laurent's site, and seemed to have forgotten that the whole point of the template was to allow the same solution to be opened in VS2008 and Blend. So anyhow, with this new perspective it looks like the templates are actually intended to use a single GUI, most likely designed entirely in Blend (with the convenience of debugging through VS2008), and then be able to use two different ViewModels -- one for design-time, and one for runtime.
So it seems to me like the answer to my question is that I want to use a combination of my previous solution, along with the MVVM Light Toolkit. The former will allow me to make multiple, distinct GUIs around my core code, while the latter will make designing fancy GUIs in Blend easier with the usage of a design-time ViewModel. Can anyone comment on this?
I checked your previous question and this one, and I had never really heard about switching projects to work in Blend and in Studio, and end up with two different UIs. I think this was not the intent of MSFT when they built Blend. Instead, the possibility to open the exact same project and code files in both IDEs (and all the discussions I had with the various teams at MSFT) hints that the intent was in fact to have one application only which can be edited in both environments.
I think that in the end, the goal is to have a variety of tools that you can use to edit your UI - XAML, Visual Studio designer, Blend. Depending on your role in the project (developer, designer, integrator) and depending on your ability with the tools, you can choose one or the other.
This doesn't mean that we never switch templates! Depending on the kind of application (for example between a SL4 desktop application or a WinPhone7 application), we use the same ViewModel (and below) code, but slap a different UI altogether on the files. I demoed how to do that in this video:
http://channel9.msdn.com/posts/kreekman/TechDays-2010-Understanding-the-Model-View-ViewModel-pattern/
This is the same talk I gave at MIX but extended by 15 minutes where I show how to reuse the ViewModel and model files, but use a completely different UI for WinPhone7.
Another application is switching templates when a window is resized (used very often in WPF, but also applicable to Silverlight) in order to show less details or a different layout for different screen sizes.
I hope that this reply doesn't confuse you :) and in fact, I'd love to hear your comments on that before we continue the discussion.
Cheers,
Laurent
I think MEFedMVVM would be a good candidate for this. It is simple and you can combine it with other frameworks.
I have a PRISM based silverlight solution under source control. In regards to theming I have a project for each theme, for example 'Theme_Summer', 'Theme_Winter' projects. In reality there may be over 30 of these theme projects. Each theme project contains a selection of resource dictionaries to hold the styles etc along with the images, sounds etc that are required.
Each of these projects also has a Main.xaml merged resource dictionary that ties together all the resources in that theme project. My main application then just uses the Main.xaml resource dictionary from whatever theme project it needs to use.
The problem I have is I need these 30 or so themes in my solution so they remain under source control and manageable but they all get compiled into the XAP which is obviously not good as the app gets deployed somewhere and only requires 1 theme.
My question is really what do people think would be a suitable approach? Having a seperate solution for each theme so that it gets compiled into a seperate XAP and loaded dynamically seems like a lot of work. Is there a way to externally load these while they are part of the same solution?
Thanks for your time
Disclaimer: What I am recommending may not be the best for you. I only know a tiny bit about your project and know nothing about what you have told the customer (or boss) what you would deliver them.
If you are going to have x (where x is between 2 and 30-ish) themes. You will probably want to spend some time building a framework for supporting x themes. Since you won't want to change this framework every time you add a new theme, PRISM is perfect for you.
I would move everything out into x-ish silverlight class libraries. Obviously you could package similar themes together, like Seasons or Holidays, which would widdle down on the numbers of projects. Now don't forget that your Visual Studio Solution can have more than one project in it (Simply right click on the project and select Add->New Project).
Using PRISM is rather simple and there are a lot of resources to help you dynamically load xap files. It sounds like you may eventually want to rid yourself of problems associated with compiling in a bunch of similar logic.
Is there a way to externally load these while they are part of the same solution?
The answer is yes! You will have to compile your individual silverlight applications into XAP files and load them with PRISM.
It may seem like a lot of work, but when you've created the first few of them, it becomes second nature and really simple to add more XAP's to your list.
http://development-guides.silverbaylabs.org/Video/Silverlight-Prism
http://msdn.microsoft.com/en-us/magazine/dd943055.aspx
http://www.sparklingclient.com/prism-silverlight/
Is it possible to develop against Silverlight and WPF using the same source code? Maybe using some #define blocks where it is necessary.
Theoretically it should be doable. It's not a big problem for the code. However, you'll have to be very careful with XAML and use only the intersecting subset of WPF and SL (1), as there's no #if/#endif for XAML.
(1) Contrary to the common belief, SL is not a proper subset of WPF. It has some features that WPF does not have, though these are being worked on.
Incidentally, PRISM (the composite application block from patterns and practices) now supports Silverlight and there's a C9 video with a quick sample on using code in both WPF and Silverlight.
I think if you stick to MV-V-VM (or something along those lines) then a lot of your backend code will be reusable, but the XAML itself might need to be forked if you want a full on "rich" experience, unless you are willing to use the VSM beta for WPF.
I have no experience on that but I have used a component that targets both WPF and Silverlight environment with the same code (there are only few differences).
The component is Chart from Visifire and it's Open Source
Maybe you can take a look into it
You can use Visual Studio file linking to include classes from WPF projects in Silverlight - but only if they don't do any UI or XAML based stuff (as this is where you will usually find inconsistencies between the two)...
So keep it to business logic etc.
Flashcards.Show application is a great example of this WPF/SL/WP7 code sharing and cross platform possibilities.
http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/03/03/flashcards-show-planning-a-cross-platform-solution.aspx
Concept of cross platform is pretty simple because everything works on .NET and a similar XAML binding system. My advice here is to invest more time on architecture of the app in terms of MVVM and other abstraction to segregate the platform dependencies. So that a major percentage of the code can be re-used across while some of the XAML might need to rewrite depends on the visual complexity of the app in different platforms.
I'm having real difficulties with XAML files in Silverlight since they get very big very fast when using Blend. It just becomes a wall of text after only a handful of controls are added and animated.
I'm hoping a better vesion of Blend will come out soon, so that our designers will never even have to see XAML. For now, though, that is not a solution - XAML still needs to be managed manually and it is a depressing task.
Has anyone found a solution to this? How do you keep your XAML files in order? How do you understand them when they get big?
Edit: I am especially interested in Silverlight solutions, since the most obvious WPF solution - splitting things up into resource dictionaries - is not supported in Silverlight.
It does require a little bit of work to maintain XAML files, but basically, what you need to do is split them up in resource files (XAML Resource Dictionaries) using a scheme that makes sense to you.
For example we use a scheme where we have a folder structure like this:
Resources (contains XAML Files that represent the user controls and pages)
Stencils (XAML files with Shapes)
Styles ( XAML Files with styles)
Brushes ( ... )
Shared
Templates ( ... )
Your structure might vary but, separating all resources in different files really makes maintenance more easy in the long run.
I have been using Silverlight 2 since January when it was in private release, and we ran into this problem, all our XAML was in one big file. What we did as best practices was to break up the user interface into separate user controls based on visual categorization (header, footer, navigation controls etc..) Originally we tried to use nested canvases (grids had not been added to the framework yet) and this turned into a maintenance nightmare later.
In Blend you can actually select a Canvas/grid etc... from the Objects and Timeline window, right click on it, and you are given the option "Make Control.." This made for speedy re factoring and modularizing our main XAML file. We then used Events to allow the user controls to communicate between each other.
Hope this helps, and good luck!
I'm a Creative Developer and work in Blend extensively.
I published a few thoughts last year on keeping XAML clean.
Silverlight currently does not support MergedResourceDictionaries so it's hard to break out the XAML into separate ResourceDictionary files as I suggested in another post.
Paul Stovell also has some interesting guidelines for XAML.