WPF without XAML
Architecturally, I think WPF is pretty amazing. In general, I'm a big fan of the underlying rendering/animation inner workings. The flexibility of the templating and styling set up is pretty impressive.
But I loathe XAML - I feel like it complicates many things. I've used it on large and small applications and I've found myself many times trying to figure out how to do something in XAML for which the underlying principle is basic but the syntax is quirky. Not only that, but I've wondered many times how heavy certain parts of the parsing/binding are. (I know it's compiled, but I'm not sure how much is still evaluated at runtime)
XAML is just one way of building and loading the visual tree. Are there any frameworks for simplifying building the visual tree in a non-XML, code-based (but still largely declarative) way? Specifically, I'm interested in frameworks that mitigate any of the following issues while retaining an MVVM approach:
Strongly typed binding. Specify that the ViewModel must conform to a specific type. I assume BaseBinding uses reflection under the hood and I'm a bit skeptical as to the speed of that, not to mention broken bindings being annoying.
Faster binding, non-
INotifyPropertyChanged
binding. It seems like some sort ofBindableProperty<T>
could be created and the binding could listen directly to that rather than receiving all ViewModel property changes. And the use of a direct callback versus a string argument would also seem to be advantageous.A different approach to resource management; again, strongly typed dictionaries of some sort could be pretty nice. I'd almost like to see styles as lambdas or something to capture the strongly typed aspect.
In summary, any frameworks that are non-XAML based, fit well with MVVM, and are strongly typed?
I support you in Xaml-free WPF. I love layout and binding capabilities of WPF but I hate XAML too. I would love that WPF could be written in plain C#, some advantages:
- Object and Collection initializers could replace Xaml instantiations. (it's a pity that xaml prefers top-down than button up).
- Binding converters could be just lambdas.
-
Styles could be just lambdas that modify an object after instantiation, no bloated
<Setter>
syntax. - DataTemplates would be just lambdas that create controls given an object
- DataTemplateSelectors would be just a DataTemplate lambda that calls other DataTemplates.
- ItemsControl Would be just a Foreach that takes a lambda (DataTemplate) and calls it again if a new item is added to the underlying collection.
- x:Names would be just variable names.
- No need for many MarkupExtensions
- x:Static
- x:Type (specially with complex generics too!)
- UserControls would be just functions.
I think way too much complexity was added to WPF to allow it to be designed. Web development has already lost this battle from the old days of FrontPage to Razor.
Simplifying? No. But everything you can do in XAML you can just do in code. For example, here's a simple Windows Ink drawing app - pretty much as simple as you could possibly make it:
No saving, no changing anything - but you can through code.
Sketchpad.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Ink;
public class Sketchpad : Application {
[STAThread]
public static void Main(){
var app = new Sketchpad();
Window root = new Window();
InkCanvas inkCanvas1 = new InkCanvas();
root.Title = "Skortchpard";
root.ResizeMode = ResizeMode.CanResizeWithGrip;
inkCanvas1.Background = Brushes.DarkSlateBlue;
inkCanvas1.DefaultDrawingAttributes.Color = Colors.SpringGreen;
inkCanvas1.DefaultDrawingAttributes.Height = 10;
inkCanvas1.DefaultDrawingAttributes.Width = 10;
root.Content = inkCanvas1;
root.Show();
app.MainWindow = root;
app.Run();
}
}
Sketchpad.csproj
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
<PropertyGroup>
<AssemblyName>Simply Sketch</AssemblyName>
<OutputPath>Bin\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Compile Include="SketchPad.cs" />
</ItemGroup>
<Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Clean">
<Delete Files="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
That's all it takes. Granted, if you want to avoid XAML, that basically means you're going to have to write a bunch of alternate .NET code, so it's kind of up to you - do you want to dump of that stuff in XAML, or would you rather write it in code?
I think the biggest benefit to doing it within VS is you get good designer support so it's typically pretty easy to visually see where everything is and goes. It's also probably less looking up the documentation and sometimes having to make a few leaps.
But WPF without XAML is possible.
You don't even need Visual Studio installed for this, just the .NET CLI and the Developer Command Prompt. Drop these two files in a folder and run msbuild
and then you can run the file in the Bin
directory.
This question definitely needs a link to the Bling UI Toolkit. It's a super-genius high-level library for animation and rich UI prototyping on top of WPF. Binding with button.Width = 100 - slider.Value
, animation like this: button.Left.Animate().Duration(500).To = label.Right
, a pixel shader compiler - amazing.
Sadly, I don't think the project is being worked on anymore. But lots of very smart ideas to give some food for thought.
There are no frameworks like this for WPF. The three things that you mention in your wishlist would be direct (and different) replacements for the components already provided by WPF. Also, replacing the binding and resource systems with your versions would make the things you like about WPF (animation, templating, etc.) unusable as they rely heavily on the binding, resources, etc.
Here are some suggestions that may improve your experience.
1. Learn to deal with XAML (I used to hate its guts too, but now that I'm used to it its great)
2. Build your own library that makes creation of the UI easy for you, in code. After all, everything that is done in XAML can be done in code just as well.
3. If you really hate INotifyPropertyChanged, and want a callback instead use a DependencyProperty instead. No event for you to raise, and you can have a callback and default values!
4.) Don't use WPF. Even though you say you love the architecture, your list of shortcomings / desired 'improvements' covers almost all of it.
> non-INotifyPropertyChanged binding.
To manually implement INotifyPropertyChanged in your viewmodell or modell is quite a lot of manual/repitative work. However I read about these alternatives
DynamicViewModel: MVVM using POCOs with .NET 4.0 :This project aims to provide a way to implement the Model View ViewModel (MVVM) architectural pattern using Plain Old CLR Objects (POCOs) while taking full advantage of .NET 4.0 DynamicObject Class. Taking advantage of the .NET 4.0 and the DynamicObject Class, we can create a type deriving from the DynamicObject Class and specify dynamic behavior at run time. Furthermore, we can implement the INotifyPropertyChanged Interface on the derived type making it a good candidate for Data Binding.
Update Controls .NET : WPF and Silverlight data binding without INotifyPropertyChanged. It discovers dependencies automatically so you don't have to manage them in your View Model. And it works with Winforms. Bind through code using events.
-
notifypropertyweaver : Uses IL weaving (via http://www.mono-project.com/Cecil) to inject INotifyPropertyChanged code into properties.
- No attributes required
- No references required
- No base class required
- Supports .net 3.5, .net 4, Silverlight 3, Silverlight 4 and Windows Phone 7
- Supports client profile mode