Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPF compatibility layer #2309

Closed
fanoI opened this issue Feb 18, 2019 · 44 comments
Closed

WPF compatibility layer #2309

fanoI opened this issue Feb 18, 2019 · 44 comments
Labels

Comments

@fanoI
Copy link

fanoI commented Feb 18, 2019

Now that WPF has been open sourced how much will be difficult for Avalonia to load a WPF project and create a cross platform UI solution? I mean I would like the be able to take the .xaml designed for WPF and all the associated classes without changes and be able to run it on MacOS and Linux.

To clarify the way in which the widgets will be drawn should be the Avalonia one (not really important if the aspect of the UI changes a little[*]) but the .xaml and the binding should not need to change.

[*] I mean if I've not enforced a style and Avalonia and WPF buttons are shaped differently makes no difference... a button is a button!

@Gillibald
Copy link
Contributor

There are plans to make this happen. We are currently waiting for the release of the whole code base of WPF to work on this.

@fanoI
Copy link
Author

fanoI commented Feb 18, 2019

If you could obtain this compatibility I think it will be a big boon for the project!

@FSharpCSharp
Copy link

I also think that the project would be an enormous step forward. Especially since Microsoft has so far concluded to make any query WPF cross-platform. Unfortunately, Microsoft still has a lot to learn here what community really means, and that you should also listen to them.

@jmacato
Copy link
Member

jmacato commented Feb 19, 2019

@fanol There'll be caveats however, mainly those controls that relies too much on Direct3D rendering, and also older 3rd party controls that uses GAC and cant be updated (may or may not be true) but other OS/renderer-agnostic classes, interfaces and controls could be included as a sort-of compatibility layer with Avalonia

@fanoI
Copy link
Author

fanoI commented Feb 19, 2019

But it will be a starting point maybe the 3rd party controls will be updated to be more xplat / work with Avalonia if you will open the GUI market for Linux / MacOs.

@grokys grokys added the question label Mar 1, 2019
@grokys
Copy link
Member

grokys commented Mar 1, 2019

I think this may be more-or-less possible at the XAML level, but in terms of writing controls, that would be a lot more difficult: Avalonia has a fundamentally different class hierarchy to WPF (yes I kinda wish I'd stuck to something more WPF-like now, but I never knew this project would take off!)

@cycpe950609
Copy link

How about using Nuget package for msbuild ? We can convert wpf code(xaml...) in to Avalonia code

@webprofusion-chrisc
Copy link

Hi, I've recently been looking at porting a WPF app to Avalonia (https://github.com/webprofusion/certify) I've had a couple of brief attempts (and given up) but the main differences I come up against is not being able to reference control instances by name (so code changes required to this.Get("ControlName") etc., and the requirement to change all the namespaces for references to control etc.

For the namespace issue it seems like a lot of controls/features could be mapped to System.Windows.* aliases but for the control instances you'd need a background xaml compiler generating the partial classes like standard WPF (perhaps Avalonia has something like this and I've missed it).

For me the barrier to adoption is being able to really try it out fully with existing code, to see if there are any real show stoppers - higher WPF compatibility (perhaps via a compatibility nuget package) would make that a lot easier and might encourage more adoption also. My use case is that I'd like to have a mac OS version of my app without throwing everything away and starting a new app in Electron etc.

@robloo
Copy link
Contributor

robloo commented Jul 30, 2019

WPF has largely been open sourced now as they are wrapping up their .net core 3.0 porting effort.

Avalonia by itself is a difficult business case to make. Largely because it is a new flavor of XAML incompatible with the rest and requires not-insignificant porting of existing controls and apps. That said, there is a very unique opportunity here to re-base the project on WPF itself (something I never thought would be possible). Of course keep all the great syntactic sugar and improvements to XAML you've added over the years but keep vanilla WPF XAML, controls (and styling) supported out of the box. Avalonia would become a superset of WPF XAML and application model.

I really like Avalonia's methodology for getting rendering functional on other platforms. If that technology was leveraged as the new rendering backend for WPF -- wow, you have something amazing here. WPF applications everywhere would start being built with Avalonia to be able to run on other platforms. There would be a quick path into the .net foundation and a lot more funding with this path too.

I agree with @webprofusion-chrisc and am looking for a way to use cross-platform XAML-based UI and C# instead of rewriting in other languages/code-bases. Call me old fashioned but the whole industry took a massive step backwards with this JavaScript non-sense that was never meant to power apps (React Native/TypeScript is a bit more palpable). We lost a lot of power in application development and getting that back would really push everyone forward.

@kekekeks
Copy link
Member

Unfortunately "basing" the project on WPF would essentially make it not cross-platform and desktop windows-only.

Also, we are currently moving to UWP's way of handling pointer events, so it would be a challenge to translate that back to legacy mouse-centric ways of WPF.

However, it should be possible to run a subset of WPF's code base on top of Avalonia, that should allow running some unmodified WPF-based applications. That's something we have plans of doing, but there are still some blockers in our code base like text layout.

@kekekeks
Copy link
Member

Also, there is #2769 which is a step towards WPF-style styles: a single style that's can be applied to a particular control and replace the old one. Those could probably also support the trigger approach of working with states.

@robloo
Copy link
Contributor

robloo commented Jul 31, 2019

Moving to the UWP flavor of XAML / App model / event system wouldn't be an issue. The issue is just creating a 3rd standard incompatible with the other two still supported by Microsoft. You already know this, but UWP is a further generalization of the ideas in WPF to support the next generation of devices that are not desktop. While this is more advanced in some ways in others they clearly rushed it and WPF is still better and much more refined.

By 'basing' the project on WPF I meant using the same 'ideas'/API not necessarily the same implementation. It's been discussed elsewhere at length with the MSFT guys on how WPF is windows-only. However, I don't really agree with that mindset. While the implementation certainly is very strongly tied to Windows and would be difficult to separate, the ideas in WPF are cross-platform ready (for desktop apps). WPF is a very powerful and generic desktop UI platform in concept/API/spec. That is separate than how it's currently implemented.

Supporting WPF-styles would be great. But there are more fundamental issues like 'Avalonia'Property all over the place instead of DependencyProperty, etc. This would all need to be standardized to the .net naming convention and API. More of an issue is the controls hierarchy etc.

@kekekeks
Copy link
Member

incompatible with the other two still supported by Microsoft

Other three, Xamarin.Forms is pretty much alive and kicking

DependencyProperty works almost exactly like StyledProperty our model with styled/direct property separation is the extension of the classic model.

Don't get me wrong, we love WPF and better compatibility and better migration paths are our goals, but I don't think we can "base" the framework on the other one. We'll end up with way too many stubs and PlatformNotSupported exceptions like uno. There would be too many tradeoffs in favor of sticking with the API of the 10+ year old technology. Even making WPF code base to run on top of our is challenging because some approaches weren't cross platform. There are things you simply can't do on certain platforms that are used by tons of WPF applications. The examples the come to mind are the input method model (the CJK and mobile require the app to expose its internal text representation), threading (some platforms only allow UI related operations from the first thread), synchronous operations (clipboard access can be async, it might be impossible to implement an inner run loop for synchronous ShowDialog), etc, etc.

@robloo
Copy link
Contributor

robloo commented Jul 31, 2019

incompatible with the other two still supported by Microsoft
Other three, Xamarin.Forms is pretty much alive and kicking

True, but I don't consider Xamarin.Forms usable for anything but form entry apps. Using native platform controls like they do isn't good for anything but the simplest apps so I pretend it doesn't exist :)

You guys are doing an amazing thing with Avalonia and you know what you are doing far more than I do. The way you are defining properties is even an improvement over WPF/UWP. I guess fundamentally what I'm trying to describe though is there is no clean path of migration. Keeping to the property example, why not just support DependencyProperty so we don't have to change 1000s of lines of code porting over larger apps? Then when the needs arise we can migrate component-by-component over to the newer ways of doing things. I think that path of migration is important and is something Microsoft themselves have forgotten about time-and-time again.

I also agree with you that it's not good to let old technology hold back from the future. A lot of the decisions you've made are certainly for the better. But a lot of things in WPF were just dropped or changed in an incompatible way that make it very difficult to switch to Avalonia without a huge effort. That is going to be a big hindrance to adoption. Think of it this way: you have a catch-22 and needs new apps developed to make the platform more popular. However, new apps won't be developed until the platform stabilizes a lot more. That said, if existing apps could just be recompiled you would have a flood of apps right away just so people could get macOS support for desktop apps. That would advance Avalonia a lot quicker.

Who knows, maybe in a few years Avalonia will be so powerful and work so well on supported platforms that it justifies rewriting a lot of code. Until then though, it's a difficult business case.

@kekekeks
Copy link
Member

We can make some kind of portability kit package with common aliases and even add compatibility mode for compiler (e. g. it would translate <Control.Style><Style>... to <Control.ControlTheme><ControlTheme>... and emit a warning). We can even add DependencyProperty in the inheritance path (AvaloniaProperty<-DependencyProperty<-(StyledProperty/DirectProperty)) and add some helpers.

I think we need some kind of a tracking issue for most common issues that arise during app porting and see what can be done about that.

@robloo
Copy link
Contributor

robloo commented Aug 1, 2019

Those are some really good ideas and definitely think it would be a big improvement to porting!

@mstr2
Copy link
Contributor

mstr2 commented Aug 12, 2019

I gave the this a shot by making Avalonia more compatible to WPF as it relates to DependencyProperty.

The code I'm working on is not yet finished, but I'd like to put my ideas up here for discussion before I spend more time developing it further. Here's the branch I'm working on: https://github.com/mstr2/Avalonia/tree/untyped-properties

Summary
The main idea is to add set of APIs that allow properties to be either typed (Avalonia-style) or untyped (WPF-style):

  • The typed API is available as usual by calling the generic registration methods like DependencyProperty.Register<TOwner, TValue>(string name, ...), which return either StyledProperty or DirectProperty.
  • The untyped API is available by calling the untyped registration methods like DependencyProperty.Register(string name, Type propertyType, Type ownerType), which return a DependencyProperty. The API of these methods is pretty much identical to WPF.

Except for renaming AvaloniaProperty->DependencyProperty, the additions and changes do not impact existing Avalonia code. The goal of the untyped API is to be a drop-in replacement for custom dependency properties that were written for WPF. It includes support for ValidateValueCallback, CoerceValueCallback and PropertyChangedCallback.

Changes

  1. Renamed AvaloniaProperty to DependencyProperty (along with all related classes, e.g. AvaloniaPropertyChangedEventArgs, AvaloniaPropertyRegistry, etc) to facilitate adding the compatibility APIs. This change impacts mainly the Avalonia codebase; for applications that use Avalonia a simple search-and-replace (AvaloniaProperty/DependencyProperty) should be all that's needed to adapt.

  2. Renamed AvaloniaProperty.Id => DependencyProperty.GlobalIndex, as well as AvaloniaProperty.IsReadOnly => DependencyProperty.ReadOnly. While it would be very uncommon for WPF applications to use these properties, they are still part of the public API.

  3. Renamed PropertyMetadata => AvaloniaPropertyMetadata to make the class name PropertyMetadata free to use for the untyped API. The common interface of all property metadata is now IPropertyMetadata:

    public interface IPropertyMetadata {
        BindingMode DefaultBindingMode { get; }
        void Merge(IPropertyMetadata baseMetadata, DependencyProperty property);
    }
    

    The new PropertyMetadata class basically implements WPF-style metadata including PropertyChangedCallback and CoerceValueCallback.

  4. A new namespace, Avalonia.Compat (in the Avalonia.Base assembly) adds FrameworkPropertyMetadata and IFrameworkInvalidatable:

    public interface IFrameworkInvalidatable {
        void InvalidateMeasure();
        void InvalidateArrange();
    }
    

    This interface will be implemented by Layoutable to support WPF-style measure/arrange invalidation from the untyped property API without requiring users to call Layoutable.AffectsMeasure / Layoutable.AffectsArrange from the static constructor of the control. The reason for placing these classes in a compat namespace is because the Framework- naming is an artifact of WPF and has no real meaning within Avalonia.

  5. DependencyProperty adds new methods for the untyped API:

    DependencyProperty AddOwner(Type ownerType)
    DependencyProperty AddOwner(Type ownerType, PropertyMetadata metadata)
    static DependencyProperty Register(string name, Type propertyType, Type ownerType)
    static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata metadata)
    static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata metadata, ValidateValueCallback validateValueCallback)
    

    Some remarks here:

    • RegisterAttached, RegisterReadOnly and RegisterAttachedReadOnly are not in yet, these methods will be implemented if this experiment should continue further.
    • The untyped APIs return DependencyProperty (even though the actual implementation is UntypedProperty), while the typed Avalonia-style APIs return derived types (StyledProperty and DirectProperty).
    • Calling the untyped AddOwner on a StyledProperty instance will succeed, while calling it on a DirectProperty instance will fail with an InvalidOperationException.
    • While validation is part of metadata in Avalonia, this is not the case for WPF. ValidateValueCallback can only be specified once, and it can't be overridden.
  6. The implementation for an untyped property is contained in UntypedProperty. This is an internal class, so it's never accessible to Avalonia users.

@robloo
Copy link
Contributor

robloo commented Aug 12, 2019

@mstr2 those look like some really good changes that are also a good compromise with old/new. I will be curious to see what more people say but I'm definitely all for this type of thinking. It definitely follows with getting more of the WPF API supported while keeping the improved Avalonia API available when developers are ready.

@kekekeks
Copy link
Member

@mstr2 Have you encountered anything that would prevent us from just making a separate DependencyProperty class that inherits form StyledProperty<object>? This approach might make more sense.

@jmacato
Copy link
Member

jmacato commented Aug 12, 2019

I agree with @kekekeks; I object at renaming AvaloniaProperty to DependencyProperty. There will be much unnecessary confusion once that's implemented and prior users of the project might have some reservations at us breaking huge swathes of their codebase (even when the fix is just simple find and replace, it'll be breaking too much of our API stability now imo).

@Gillibald
Copy link
Contributor

Find and replace also works on the Wpf side. If there is some Avalonia API that does the same as the Wpf one there can be simply a 1:1 mapping.

There could be some converter that does the conversion automatically. It will not be possible to use a WPF Third-party control within Avalonia without recompilation of the Third-party control library.

If a feature is missing in Avalonia that Wpf has and that is commonly used it could be added to the main code base if not it should be in the compat assembly. App compat should be on top of Avalonia API if there is no 1:1 mapping.

I think for better compatibility with Wpf we need support for visual states. Triggers etc. can be could be simply added by some transformation logic that adds a style with a appropriate selector to Control.Style. The addition of Control.Style would help a lot to make this possible.

Maybe we should make a list of features that are not available within Avalonia and a list of features that are already there. That would help to prioritize new features etc.

@mstr2
Copy link
Contributor

mstr2 commented Aug 12, 2019

@mstr2 Have you encountered anything that would prevent us from just making a separate DependencyProperty class that inherits form StyledProperty<object>? This approach might make more sense.

I considered adding DependencyProperty at the top of the inheritance path (i.e. DependencyProperty <- StyledProperty <- AvaloniaProperty) and at the bottom of the inheritance path (i.e. StyledProperty <- DependencyProperty).

I've found that the first option requires the most "hacks" to make it work, for instance:

  • If DependencyProperty is-a StyledProperty, (DP-)PropertyMetadata also needs to extend StyledPropertyMetadata. That's because StyledProperty.GetMetadata could be called on an instance of DependencyProperty. Currently, StyledProperty.GetMetadata hides its base method, but doesn't violate the expectation that the returned metadata types are related. The problem is that (DP-)PropertyMetadata is very different from StyledPropertyMetadata, so that it can't be a subclass of it.
  • None of the typed property classes forward the property value type to the base AvaloniaProperty. Having an untyped DependencyProperty at the top of the inheritance path would necessitate passing along the type information along the entire inheritance chain using separate constructors.
  • AvaloniaPropertyChangedEventArgs needs to be converted to DependencyPropertyChangedEventArgs at some point.
  • Since the untyped DependencyProperty would include all of the typed API, we'd either have all of the typed API throw InvalidOperationException, or retain the ones that can be adapted (e.g. OverrideDefaultValue), while throwing InvalidOperationException for the ones that can't be adapted (e.g. OverrideValidation).

In general, I've found that adding DependencyProperty at the top introduces many APIs into DependencyProperty that can't easily be made compatible.

@mstr2
Copy link
Contributor

mstr2 commented Aug 12, 2019

@jmacato
When it comes to breaking changes, keep in mind that Avalonia has not yet guaranteed a stable API. I guess it kind of depends on how important compatibility will be for this project. If it is deemed important, then the amount of existing WPF code dwarfs the amount of existing Avalonia code.

@Gillibald
It's not just about a one-time conversion or a find-and-replace on the WPF side. My perspective on this issue, coming from one of the big Silicon Valley companies, is that it's a very hard sell at the moment to invest into an Avalonia-based project considering it's an unproven technology with a doubtful future.

If the project was closer aligned to WPF, people could get more creative and try different things, for example dual-targeting their codebase for both frameworks. Of course that is not an easy thing to do, but every step into that direction makes it more likely that people will give it a try.

It's also not only about third-party controls. For example, people have been using DependencyProperty on view models, and maybe they will want to keep the untyped API for the time being.

In the end, WPF compatibility will be the combination of lots of things. Some of them can be built on top of Avalonia, some need to be integrated more deeply in order to make them work. DependencyProperty is only one little aspect of the problem.

@Gillibald
Copy link
Contributor

One argument for a deeper integration, renaming and adaption of the DependencyProperty API is the fact that it would make it easier to port existing Third-party controls that currently target Wpf. Especially the way coercion is handled differs between the two platforms.

As you mentioned this is only one piece of several.

@robloo
Copy link
Contributor

robloo commented Aug 15, 2019

@mstr2 has thought this out quite a bit and I have to agree with every one of his points (although I'm a bit biased as I want this myself). I think we need to try to make it as compatible with WPF as possible. Of course I'm not asking you to sacrifice any of the improved API -- that should just be a newer API available with the older WPF API.

the amount of existing WPF code dwarfs the amount of existing Avalonia code.

@valters-tomsons
Copy link
Contributor

If the WPF is so different, why not do it offline?
Maybe a tool to convert from WPF XAML to Avalonia XAML would be feasible to create?

@kekekeks
Copy link
Member

kekekeks commented Oct 1, 2019

The plan for the immediate future is to make our XAML more compatible first:

  • control themes that work essentially in the same way as WPF styles
  • Triggers
  • Storyboards
  • "compatibility" mode for XAML compiler that would rewrite WPF XAML to Avalonia XAML when it makes sense (e. g. convert <Button.Style> to <Button.ControlTheme>)

@mstr2
Copy link
Contributor

mstr2 commented Oct 1, 2019

@kekekeks
That covers many important aspects of XAML, but do you have any further ideas about a WPF-style untyped property implementation?
This is not only relevant with respect to porting WPF controls that are built on this API. Untyped dependency properties also often used in view model classes, and it's a rather big thing for existing WPF codebases that could otherwise have a pretty straightforward conversion path to Avalonia (if the legacy API was available).

@robloo
Copy link
Contributor

robloo commented Oct 14, 2019

@grokys @kekekeks
I think @mstr2 has another good point with the above comment. Would you accept a pull request adding traditional/legacy DependencyProperty support? This will help in a lot of areas in the porting process and also remove a barrier of entry to people coming over from the WPF/UWP world.

There wouldn't be too much of an issue as you already have StyledProperty and AvaloniaProperty named differently. It's just some metadata classes that have to be renamed it seems.

@jmacato
Copy link
Member

jmacato commented Oct 14, 2019

@robloo I think it needs to be in a separate layer that is optional and hopefully is just a thin layer over AvaloniaProperties

@robloo
Copy link
Contributor

robloo commented Oct 14, 2019

@jmacato Ok, I'm curious why you seem to have an aversion to adding this? Do you think it muddies up the API? Do you think it will encourage developers to always fall back to the untyped property API?

To the first I would say it actually allows developers to transition at their own pace and keep a lot of existing code. To the second I would say it's ultimately up to the developer to choose what suits their needs.

@jmacato
Copy link
Member

jmacato commented Oct 14, 2019

No, personally im okay with the idea of having a WPF compatibility layer. But I dont like the fact that it is going to be integrated in the core repo simply because it'll be yet another maintainance burden. And I personally want the first-time users of Avalonia to use the correct/native Avalonia patterns instead of defaulting to WPF's. If they want to use WPF specific stuff then they can just add a nuget package of the compatibility layer and be done with it.

@mstr2
Copy link
Contributor

mstr2 commented Oct 18, 2019

I gave this another shot and tried to make it an add-on layer instead. Here's the branch: https://github.com/mstr2/Avalonia/tree/compat

The compatibility layer lives in the Avalonia.Compatibility assembly.

Breaking changes

  1. PropertyMetadata was renamed to AvaloniaPropertyMetadata to make the former name available for WPF-style metadata. This shouldn't cause too many issues, since it's only used as a base class for StyledPropertyMetadata and DirectPropertyMetadata so far.

  2. Trying to change the value of a read-only property now throws InvalidOperationException instead of ArgumentException, because that's what WPF throws.

DependencyObject = AvaloniaObject
We need to keep AvaloniaObject as the base class because it already used by many other classes in the framework. For legacy codebases, it can be aliased as DependencyObject with a using directive.

DependencyProperty
DependencyProperty is implemented in terms of StyledProperty<object>. It adds all of the Register / RegisterReadOnly / RegisterAttached / RegisterAttachedReadOnly methods, which return a DependencyProperty instance.

The behavior of DependencyProperty is slightly different from AvaloniaProperty in some aspects. For example, while AvaloniaProperty supports setting an int value to a double property by implicit conversion, DependencyProperty does not.

Read-only dependency properties
WPF's DependencyObject supports changing the values of read-only properties with the SetValue(DependencyPropertyKey, object) method.

In order to support this scenario without introducing the "property key" concept into the public Avalonia API, the untyped AvaloniaObject.SetValue(AvaloniaProperty, object, BindingMode) now takes in a IAvaloniaProperty interface reference instead (of which AvaloniaProperty is the only implementation in the base framework).

Internally, the implementation checks whether the IAvaloniaProperty instance is actually an IAvaloniaPropertyKey (which is also internal), and if it is, it retrieves the actual AvaloniaProperty from it.

The only implementation of IAvaloniaPropertyKey is the WPF-style DependencyPropertyKey class in the compatibility assembly.

EventManager
EventManager is provided to register untyped routed events. In order to make this a drop-in replacement, RoutingStrategies needs to be aliased with RoutingStrategy.

What's left
I've had some limited success in trying to port a WPF control. While most of the dependency properties I've encountered are covered by the compatibility layer, most of the input handling is not. This includes things like Keyboard, Mouse, AccessKeyManager, etc.

The other major missing piece is the XAML side with support for styles, storyboards and triggers.

@jmacato
Copy link
Member

jmacato commented Oct 18, 2019

@mstr2 this looks good! Though i wonder how the mouse-centric paradigm of WPF would translate to the new UWP-style Pointers that we adopted in 0.9... But anyway i like this approach of an add-on module 👍

@kekekeks
Copy link
Member

This includes things like Keyboard, Mouse, AccessKeyManager, etc.

Just to make it clear, we are not adding static classes with static variables/properties inside.

@kekekeks
Copy link
Member

@jmacato unfortunately WPF wasn't designed with multiple pointers and multiple pointer devices in mind. So mouse input code has to be ported manually.

@kekekeks
Copy link
Member

A way for emulating Mouse/Keyboard would be to create MouseCompatHelper/KeyboardCompatHelper and use those as properties

@grokys
Copy link
Member

grokys commented Oct 19, 2019

@mstr2 that's great! If a WPF-compatibility layer could be done as a community effort, even in a separate repository, I think that would be ideal. The problem is the moment something enters the main Avalonia repository, we the maintainers become responsible for its maintenance forever, and we've already got too much to do! We've had many instances where we've said to a contributor "we'll accept this, but do you promise to stick around to maintain it?" and they've said "yes" and then they disappear.

Of course we could/would support you by making changes to the Avalonia API if necessary.

@mstr2
Copy link
Contributor

mstr2 commented Oct 19, 2019

It doesn’t seem to work without a few of the changes to the core repo that I’ve described (mainly to support read-only DPs).

Also, I think Avalonia.Base should expose it’s internals to the compat assembly instead of making IAvaloniaPropertyKey public, otherwise it would kind of become public API. It seems like this would make the compact assembly a part of the Avalonia project.

The DP layer is pretty lean and feels kind of natural, maybe there’s value in only including this part for the moment and seeing whether people find it useful.

Legacy input handling could be added in the future if it turns out there is actually a need for that (maybe there isn’t?).

If at some point there’s support for storyboards, triggers, etc. I can see these things adding up to a pretty straightforward migration path.

@danwalmsley
Copy link
Member

@mstr2 if there was a todo list for this compatibility layer, that meant you could just recompile a wpf program and run it on avalonia, what would that look like?

@danwalmsley
Copy link
Member

@mstr2 I also know a nice nuget package that will give you access to our internals, iv used it to gain access to Roslyn api, and you could use it for us too, if it helps...
https://github.com/aelij/IgnoresAccessChecksToGenerator

@mstr2
Copy link
Contributor

mstr2 commented Oct 22, 2019

@danwalmsley
For a WPF control, the migration todo list could look something like this:

  1. Reference Avalonia.Compatibility and add some aliases:

    using DependencyObject = Avalonia.AvaloniaObject;
    using DependencyPropertyChangedEventArgs = Avalonia.AvaloniaPropertyChangedEventArgs;

    This allows you to create dependency objects with dependency properties. Most common scenarios should work out of the box, including validation and value coercion.

    Note: if a property is defined on a ILayoutable and specifies FrameworkPropertyMetadata with the AffectsMeasure or AffectsArrange flags, the implementation will call ILayoutable.InvalidateMeasure() and ILayoutable.InvalidateArrange() as needed.

  2. If your control contains routed events, add:

    using RoutingStrategy = Avalonia.RoutingStrategies;

    Most common scenarios should also work out of the box.

  3. If your control overrides FrameworkElement.OnApplyTemplate(), you need to port it to use the Avalonia APIs. This probably means replacing GetTemplateChild with e.NameScope.Find.

  4. If your control uses input APIs (for example, it overrides OnMouseUp(MouseButtonEventArgs), you need to manually port this code to use Avalonia APIs.

  5. Port the XAML part of your control. This is not quite as straightforward if the control uses features that Avalonia currently does not support, like storyboards, triggers, etc.
    Also, concepts like default styles do not translate easily to Avalonia.

@robloo
Copy link
Contributor

robloo commented Oct 14, 2023

Should this be closed now? The "WPF Compatibility Layer" is really Avalonia XPF now. It seems this is the final direction:

  • Avalonia XPF for complete WPF compatibility
  • AvaloniaUI for continued advancement but object model changes from WPF. I do expect more convergence over time.
  • Hosting Avalonia in WPF and vice versa

@maxkatz6
Copy link
Member

I believe so. It is possible to use XPF cross-platform on top of Avalonia engine. And two-way embedding is also supported already.

https://avaloniaui.net/XPF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests