The release of the first beta version of Avalonia .
Avalonia is a cross-platform .NET UI toolkit inspired by WPF technologies and distributed under the MIT license. It fully supports .NET Core 2.0, XAML, data bindings, lookless controls, and more. Avalonia allows you to write applications on C # under Windows, Linux and Mac OS X. The ability to run on iOS and Android is in an experimental state.
This version is stable and has the full right to be called a beta: the toolkit does not fall apart in the hands and has a decent basic set of controls (see video). It has created two fairly large open source applications: AvalonStudio is a cross-platform IDE for developing in C # and C ++ and Core2D is an editor for 2D diagrams and diagrams.
The easiest way to take and start using is to install our extension for Visual Studio or use the templates for dotnet new . For examples examples are available in the main repository .
During the preparation of the release, a number of important changes occurred:
Key features in the release
Previously, the window was completely redrawn with each change. This approach is simple and reliable, but extremely inefficient. Instead , a DeferredRenderer
was implemented , which converts the calls to our rendering API into a window scene graph . A separate stream searches for modified sections in the graph and redraws only them. In addition to removing the load from the UI stream, this allows you to add optimizations, highlighting parts of the window in cached layers.
New rendering infrastructure significantly improved performance, especially in cases with animations. It also gave us the opportunity to implement properly working hit-testing.
If you have problems using the new infrastructure, the old ImmediateRenderer
implementation is left for compatibility.
Since GTK2 / GTK3 are heavy libraries (~ 60MB), and were used only for the sake of the wrapper over the native Carbon API, we implemented the Cocoa backend using the specially built .NET Standard MonoMac. This simplified the assembly of bundles and allowed the use of native OS X file dialogs instead of the "universal" ones provided by GTK.
Earlier, as in WPF, bindings to other controls were done via RelativeSource
. This syntax is very verbose: for example, binding text to the Tag
property of the parent element looks like this:
<Border Tag="Hello World"> <TextBlock Text="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Border} AncestorLevel=1}}"/> </Border>
The new syntax allows you to rewrite it like this:
<Border Tag="Hello World"> <TextBlock Text="{Binding $parent.Tag}"/> </Border>
In addition to the $parent
keyword, the following features have been added:
Reduction | Full form |
---|---|
$self | Mode = Self |
$parent | Mode = FindAncestor; AncestorLevel = 1 |
$parent[Level] | Mode = FindAncestor; AncestorLevel = Level +1 |
$parent[ns:Type] | Mode = FindAncestor; AncestorType = ns:Type |
$parent[ns:Type; Level] | Mode = FindAncestor; AncestorType = ns:Type; AncestorLevel = Level + 1 |
* ns:Type
- namespace: Type, for example Border
or local:MyControl
Drawing
is a convenient representation for vector graphics of the type of icons used in WPF. Visual Studio Image Library provides hundreds of icons in this format. Their use improves performance, since all parts of the image are one element of the visual tree .
Now in Avalonia there is support for this format. Our standard Image
control does not know how to work with them yet, but you can already use DrawingPresenter
.
StaticResource
and DynamicResource
The new version adds the usual WPF / UWP Control.Resources
, StaticResource
and DynamicResource
.
The implementation exactly corresponds to the similar functionality in WPF / UWP. Earlier, all resources were tied to styles and it was suggested to use {StyleResource}
to access them. Now each control has its own dictionary of resources that are inherited through the element tree. The {StyleResource}
markup {StyleResource}
been removed: now {DynamicResource}
should be used {DynamicResource}
.
I think everyone has an ICommand
implementation in the project that accepts a delegate in the constructor. In order not to produce unnecessary entities, binding directly to the methods of the view model is added to the framework itself.
public class ViewModel { public void ButtonClicked() { Console.WriteLine("Hooray!"); } }
<Button Command="{Binding ButtonClicked}"/>
Was dragged from the Silverlight Toolkit . Now you can choose dates.
In the new version, the Avaloniya components can be completely seamlessly embedded in applications on WPF. This became possible due to the fact that the layout systems in Avaloniya and WPF are almost identical, and Direct2D using black magic can render directly into the sharpened Direct3D 9 D3DBitmap
. You can see the demo here .
It is curious that due to the use of Direct2D with such integration on complex scenes, the performance difference can reach two orders of magnitude in favor of Avaloniya. If you have a decelerating control for WPF, it may make sense to try porting it and building it back.
The previous version of the preview for the studio was written in three days with all possible angles cut off. As a result, it turned out to be tied to the Win32 API, full of the .NET Framework and Windows Forms. Now, instead of it, a more intelligent system was invented, with communication over TCP / IP and the ability to transfer bitmaps instead of direct integration of the window in Visual Studio. This allowed the normal preview of XAML in projects under .NET Core and, more importantly, opened the way for support in other IDEs. In particular, support has already been added to AvalonStudio. Work is underway on the Visual Studio Code plugin, but this is difficult: this IDE is built on advanced and progressive web technologies and requires a separate language-server, binding around MSBuild and sending images via WebSocket.
In addition to the previewer, the “remote” widget infrastructure can be useful somewhere else, so the classes RemoteServer
and RemoteWidget
are available for use.
A complete list can be found here , and below are the most interesting points:
#894
Buttons are turned off if the binding of the Command
property returns null
#1085
Added FindAncestor
#1086
ReactiveUI updated to the eighth version#1128
The button has IsPressed
property#1133
IsOpen
, Placement
, Offset
implemented for IsOpen
#1145
Moved to .NET Standard 2.0#1146
ShowTaskbarIcon
property is implemented for a window#1150
Implemented screen access API#1174
#1175
Orientation
and IsIndeterminate
in progress indicator#1253
Vertical orientation implemented for PageSlide animation#1265
Implemented support of three states for ToggleButton
, CheckBox
and RadioButton
(gray no-yes-no-no)#1273
Simplified setting up logging when setting up AppBuilderThe good news is that we are tracking them now and sometimes even documenting them .
The bad news: they are.
BuildAvaloniaApp
for previewer.To work, a new previewer needs to obtain information from the application itself. To do this, the BuildAvaloniaApp
method should be implemented in a class with an entry point (usually Program.cs
right next to Main
), something like this:
static void Main(string[] args) { BuildAvaloniaApp().Start<MainWindow>(); } public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>() .UsePlatformDetect() .LogToDebug();
Without it, the preview will not work. So it goes.
DataContextChanging
and DataContextChanged
Replaced with OnDataContextBeginUpdate
and OnDataContextEndUpdate
.
Static
and Type
Replaced by x:Static
and x:Type
, you need to add the xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
space to the root element of the XAML file. For standardization.
StyleResource
StyleResource
replaced by StaticResource
and DynamicResource
, as in all normal XAML frameworks. StaticResource
and DynamicResource
look in Control.Resources
and Style.Resources
.
Removed one of the global variables - MouseDevice
. Now the mouse is available at the top level: call GetVisualRoot
and bring the result to IInputRoot
. That's because global variables and service locator are evil.
var pos = (_control.GetVisualRoot() as IInputRoot)?.MouseDevice?.Position ?? default(Point);
Download addition to the Studio and create a project from the template. There is no full-fledged documentation yet, so experience with WPF or UWP is needed.
Source: https://habr.com/ru/post/349394/
All Articles