### Install Avalonia.Markup.Declarative Templates Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/readme.md Installs the project template for creating new Avalonia.Markup.Declarative projects. ```bash dotnet new install Declarative.Avalonia.Templates dotnet new avalonia-declarative -n MyApp ``` -------------------------------- ### Install Declarative.Avalonia.Templates Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/Templates/Declarative.Avalonia.Templates/README.md Installs the Avalonia declarative UI project template using the .NET CLI. ```bash dotnet new install Declarative.Avalonia.Templates ``` -------------------------------- ### View Initialization Examples Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/types.md Demonstrates how to use ViewInitializationStrategy for lazy and immediate view initialization, and how to set the global default. ```csharp // Use lazy initialization (default) var lazyView = new MyView(); // Not initialized yet var control = lazyView.Child; // Now initialized on first access // Use immediate initialization public class EagerView : ViewBase { public EagerView() : base(ViewInitializationStrategy.Immediate) { // View is initialized immediately } } // Set global default AppBuilder.Configure() .UseViewInitializationStrategy(ViewInitializationStrategy.Immediate); ``` -------------------------------- ### Legacy Tool Installation and Usage Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/GenerateMarkupExtensionsForAssemblyAttribute.md Example of installing and using the legacy `avalonia-amd-gen` command-line tool. This approach is no longer required with the current source generator. ```bash dotnet tool install avalonia-amd-gen avalonia-amd-gen --project MyProject.csproj ``` -------------------------------- ### Minimal Avalonia App Setup Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/configuration.md This snippet shows the most basic configuration for an Avalonia application. It sets up the application builder and starts the classic desktop lifetime. ```csharp public class Program { public static void Main(string[] args) { BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); } public static AppBuilder BuildAvaloniaApp() { return AppBuilder.Configure() .UsePlatformDetect() .LogToTrace(); } } ``` -------------------------------- ### ViewBase Usage Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Example of creating and manually initializing a custom view that inherits from ViewBase. ```csharp public class MyView : ViewBase { protected override object Build() { return new StackPanel() .Children( new TextBlock().Text("Hello"), new Button().Content("Click me") ); } } // Usage var view = new MyView(); view.Initialize(); // Manual initialization if needed ``` -------------------------------- ### Full Featured Avalonia App Setup with DI Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/configuration.md This snippet demonstrates a comprehensive setup including dependency injection configuration, declarative markup, and hot reload. It's suitable for complex applications requiring service management. ```csharp public class Program { public static void Main(string[] args) { BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); } public static AppBuilder BuildAvaloniaApp() { // Configure dependency injection var services = new ServiceCollection() .AddSingleton(new ConsoleLogger()) .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .BuildServiceProvider(); return AppBuilder.Configure() .UsePlatformDetect() .LogToTrace() // Configure declarative markup .UseServiceProvider(services) .UseComponentControlFactory(type => (Control)ActivatorUtilities.CreateInstance(services, type)) .UseViewInitializationStrategy(ViewInitializationStrategy.Lazy) .UseHotReload(isDevelopment: true); } } ``` -------------------------------- ### Example Implementation of ViewBase Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Demonstrates how to subclass ViewBase to create a CounterView. It initializes the view model in the constructor and implements the Build method to define the UI. ```csharp public class CounterView : ViewBase { public CounterView() : base(new CounterViewModel()) { } protected override object Build(CounterViewModel vm) { return new StackPanel() .Children( new TextBlock() .Text(vm, x => x.DisplayText), new Button() .Content("Increment") .OnClick(_ => vm.Increment()) ); } } ``` -------------------------------- ### IReloadable Implementation Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/Interfaces.md Example of implementing the IReloadable interface in a custom view. The ViewBase class provides a default implementation that clears the visual tree and reinitializes. ```csharp public class MyView : ViewBase, IReloadable { public void Reload() { // ViewBase provides implementation // Clears visual tree and calls Initialize() } } ``` -------------------------------- ### ViewBase Build Method Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Abstract method that must be implemented by subclasses to return the root control or control hierarchy for the view. ```csharp protected abstract object Build() // Example implementation: protected override object Build() { return new StackPanel() .Children( new TextBlock().Text("Content") ); } ``` -------------------------------- ### Complete Avalonia Application Configuration Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/AppBuilderExtensions.md Demonstrates setting up dependency injection and configuring the Avalonia AppBuilder with declarative markup extensions. This includes using `UseServiceProvider`, `UseComponentControlFactory`, `UseViewInitializationStrategy`, and `UseHotReload`. ```csharp // Program.cs using Microsoft.Extensions.DependencyInjection; using Avalonia.Markup.Declarative; public static class Program { [STAThread] public static void Main(string[] args) { var app = BuildAvaloniaApp(); app.StartWithClassicDesktopLifetime(args); } public static AppBuilder BuildAvaloniaApp() { // Set up dependency injection var services = new ServiceCollection() .AddSingleton() .AddSingleton() .AddSingleton() .BuildServiceProvider(); return AppBuilder.Configure() .UsePlatformDetect() .LogToTrace() // Configure declarative markup .UseServiceProvider(services) .UseComponentControlFactory(type => (Control)ActivatorUtilities.CreateInstance(services, type)) .UseViewInitializationStrategy(ViewInitializationStrategy.Lazy) .UseHotReload(true); } } // Usage in views public class MainView : ViewBase { public MainView() : base(new MainViewModel()) { } protected override object Build(MainViewModel vm) { return new StackPanel() .Children( new TextBlock().Text("Configured Application"), new Button().Content("Click me") ); } } ``` -------------------------------- ### IDeclarativeViewBase Usage Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/Interfaces.md Example demonstrating how a custom view inherits from ViewBase and implicitly implements IDeclarativeViewBase. This enables the generation of markup extensions for the custom control. ```csharp // Any ViewBase-derived class automatically implements this public class MyCustomView : ViewBase { protected override object Build() => new TextBlock(); } // This automatically gets markup extensions generated: // public static MyCustomView Foo(this MyCustomView control, string value) => ... ``` -------------------------------- ### ViewBase OnAfterInitialized Method Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Called after the view has been successfully initialized. Override for post-initialization setup. ```csharp protected virtual void OnAfterInitialized() ``` -------------------------------- ### Basic View Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/README.md Demonstrates how to create a simple view with a text block and a button using Avalonia Markup Declarative. This is suitable for straightforward UI layouts. ```csharp using Avalonia.Markup.Declarative; public class HelloView : ViewBase { protected override object Build() { return new StackPanel() .Children( new TextBlock() .Text("Hello, World!"), new Button() .Content("Click me") .OnClick(_ => MessageBox.Show("Clicked!")) ); } } ``` -------------------------------- ### Handling Compiled Binding Setup Errors Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/errors.md This example demonstrates how ViewBuildingException is thrown when there are issues during compiled binding setup, such as a non-existent property or a type mismatch. The exception is thrown directly from the _setCompiledBinding method. ```csharp new TextBox() ._setCompiledBinding(TextBox.TextProperty, viewModel, x => x.InvalidProperty) // ViewBuildingException: Property doesn't exist or type mismatch ``` -------------------------------- ### Application Setup Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/README.md Shows the essential code for setting up and running an Avalonia application, including service registration and lifetime management. This is the entry point for your Avalonia application. ```csharp public static class Program { public static void Main(string[] args) { BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); } public static AppBuilder BuildAvaloniaApp() { var services = new ServiceCollection() .AddSingleton() .AddSingleton() .BuildServiceProvider(); return AppBuilder.Configure() .UsePlatformDetect() .LogToTrace() .UseServiceProvider(services) .UseComponentControlFactory(type => (Control)ActivatorUtilities.CreateInstance(services, type)) .UseHotReload(true); } } ``` -------------------------------- ### Create New Avalonia Declarative App Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/Templates/Declarative.Avalonia.Templates/README.md Creates a new Avalonia application named 'MyApp' using the installed declarative template. ```bash dotnet new avalonia-declarative -n MyApp ``` -------------------------------- ### Using Source-Generated Factories Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewFactoryRegistry.md Example of how to use ViewFactory.Create() when control factories are automatically registered by the source generator. This is typically done in application startup code. ```csharp // In Program.cs or startup code, source generation automatically registers: // ViewFactoryRegistry.Register(() => new MyView()); // Usage: var view = ViewFactory.Create(); ``` -------------------------------- ### AppBuilderExtensions.md Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/README.md Application setup extensions for Avalonia.Markup.Declarative, including service provider configuration, control factory registration, and hot reload enablement. ```APIDOC ## Application Setup Extensions ### Description Methods for configuring the Avalonia application setup process. This includes integrating dependency injection, registering custom control factories, setting view initialization strategies, and enabling hot reload. ### Methods - **Service Provider Configuration**: Integrate with `IServiceProvider` for dependency injection. - **Control Factory Registration**: Register custom factories for creating controls. - **View Initialization Strategy**: Configure how views are initialized. - **Hot Reload Enablement**: Activate hot reload functionality for .NET 6.0+. ``` -------------------------------- ### ViewBase BuildStyles Method Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Optionally returns a StyleGroup for view-local styles. Override to define custom styles for controls within the view. ```csharp protected virtual StyleGroup? BuildStyles() { return new StyleGroup() .Add(new Style() .Selector(s => s.OfType()) .Setter(TextBlock.ForegroundProperty, Brushes.Blue)); } ``` -------------------------------- ### ViewBase OnCreated Method Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Called before the view is initialized and built. Override this method to perform setup tasks before child controls are created. ```csharp protected virtual void OnCreated() { // Initialize resources, subscriptions, etc. } ``` -------------------------------- ### Declarative Component Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/readme.md Demonstrates a self-contained declarative component using C# for Avalonia UI. It includes a reactive state management using CommunityToolkit.Mvvm. ```csharp using Avalonia.Data; using CommunityToolkit.Mvvm.ComponentModel; public class CounterComponent() : ViewBase(new State()) { public sealed partial class State : ObservableObject { [ObservableProperty] [NotifyPropertyChangedFor(nameof(CounterLabel))] public partial decimal? Counter { get; set; } = 0; [ObservableProperty] public partial string StatusText { get; set; } = "Hello world"; public string CounterLabel => $"Counter: {Counter}"; } protected override object Build(State state) => new StackPanel() .Children( new TextBlock() .Text(state, x => x.StatusText), new TextBlock() .Text(state, x => x.CounterLabel), new NumericUpDown() .Value(state, x => x.Counter, BindingMode.TwoWay), new Button() .Content("Increment") .OnClick(_ => state.Counter++) ); } ``` -------------------------------- ### MVVM View Example Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/README.md Illustrates creating a view that follows the MVVM pattern, binding UI elements to a ViewModel for data and command interactions. Use this for more complex applications requiring separation of concerns. ```csharp using Avalonia.Markup.Declarative; using Avalonia.Data; public class CounterView : ViewBase { public CounterView() : base(new CounterViewModel()) { } protected override object Build(CounterViewModel vm) { return new StackPanel() .Children( new TextBlock() .Text(vm, x => x.Count), new Button() .Content("Increment") .OnClick(_ => vm.Increment()), new NumericUpDown() .Value(vm, x => x.Count, BindingMode.TwoWay) ); } } ``` -------------------------------- ### ViewFactory Usage Flow Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewFactoryRegistry.md Illustrates the sequence of checks performed by ViewFactory.Create() to instantiate a control, starting from component control factories to fallback mechanisms. ```text User Code ↓ ViewFactory.Create() ↓ 1. Check AppBuilderExtensions.ComponentControlFactory 2. Check ViewFactoryRegistry.TryCreate() 3. Fall back to Activator.CreateInstance() ↓ Control Instance ``` -------------------------------- ### OnAfterInitialized() Method Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md The protected virtual OnAfterInitialized() method is called after the view has been successfully initialized. It can be overridden to perform post-initialization setup. ```APIDOC ## OnAfterInitialized() ```csharp protected virtual void OnAfterInitialized() ``` Called after the view has been successfully initialized. Override to perform post-initialization setup. ``` -------------------------------- ### Style Configuration via BuildStyles Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/configuration.md Define styles for views by overriding the BuildStyles method. This example demonstrates styling a TextBlock with specific foreground and font size. ```csharp public class StyledView : ViewBase { protected override object Build() => new TextBlock().Text("Styled content"); protected override StyleGroup? BuildStyles() { return new StyleGroup() .Add(new Style() .Setter(TextBlock.ForegroundProperty, Brushes.Blue) .Setter(TextBlock.FontSizeProperty, 14)); } } ``` -------------------------------- ### Internal DefaultViewInitializationStrategy Property Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/AppBuilderExtensions.md Gets the default view initialization strategy set via `UseViewInitializationStrategy()`. Used by `ViewBase` constructors. ```csharp internal static ViewInitializationStrategy DefaultViewInitializationStrategy { get; } ``` -------------------------------- ### Catching ViewBuildingException Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md Example of how to catch and handle ViewBuildingException. The exception message includes file path and line number, and the inner exception provides the root cause. ```csharp try { var view = new MyView(); } catch (ViewBuildingException ex) { // ex.Message includes file path and line number // ex.InnerException is the root cause Console.WriteLine($"Build failed: {ex.Message}"); } ``` -------------------------------- ### Handling Binary Compatibility Issues with ViewBuildingException Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/errors.md This example illustrates how ViewBuildingException is used to signal binary compatibility issues, often due to Avalonia version mismatches or dependency problems. The exception message provides specific context about the compatibility problem. ```csharp // ViewBuildingException with special message about binary compatibility // Usually indicates: Avalonia version mismatch or dependency issue ``` -------------------------------- ### Generated Code Example by Source Generator Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewFactoryRegistry.md This code demonstrates the structure of C# code automatically generated by the source generator for registering custom control factories and fluent extension methods. ```csharp // This is what the source generator produces in your project: [module: CompilerFeature("RefStructs")] namespace GeneratedMarkupExtensions { public static class MarkupExtensions { // Generated when a custom control needs factory registration static MarkupExtensions() { ViewFactoryRegistry.Register(() => new MyCustomControl()); } // Generated fluent extension methods for MyCustomControl public static MyCustomControl Text(this MyCustomControl control, string value) => control._set(() => { /* ... */ }); } } ``` -------------------------------- ### OnCreated() Method Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/ViewBase.md The protected virtual OnCreated() method is called before initialization and building of the UI. It can be overridden to run setup code before child controls are created. ```APIDOC ## OnCreated() ```csharp protected virtual void OnCreated() ``` Called before initialization and building of the UI. Override to run setup code before child controls are created. **Example:** ```csharp protected override void OnCreated() { // Initialize resources, subscriptions, etc. } ``` ``` -------------------------------- ### Using GenerateMarkupExtensionsForAssembly with a Custom Library Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/GenerateMarkupExtensionsForAssemblyAttribute.md Generate fluent extensions for custom controls defined in a separate project. This example shows how to apply the attribute to ProjectA.Controls.AdvancedPanel and then use the generated extensions in ProjectB. ```csharp // ProjectA: Defines custom controls namespace ProjectA.Controls { public class AdvancedPanel : Panel { public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register(nameof(Spacing)); public double Spacing { /* ... */ } } public class AdvancedButton : Button { // Custom properties and logic } } // ProjectB: Uses ProjectA controls declaratively using Avalonia.Markup.Declarative; using ProjectA.Controls; [assembly: GenerateMarkupExtensionsForAssembly(typeof(AdvancedPanel))] public class MyView : ViewBase { protected override object Build() { // Generated extensions for AdvancedPanel and AdvancedButton return new AdvancedPanel() .Children( new AdvancedButton() .Content("Custom Control") ); } } ``` -------------------------------- ### Create and apply an untyped selector to a style Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/_autodocs/api-reference/StylePropertyExtensions.md Use this method to create an untyped style and apply a selector. The selector function receives null as the starting selector. ```csharp var style = new Style() .Selector(s => new Selector().OfType().Class("highlight")) .Setter(TextBlock.ForegroundProperty, Brushes.Red); ``` -------------------------------- ### Equivalent XAML for MVVM View Source: https://github.com/avaloniaui/avalonia.markup.declarative/blob/master/readme.md This XAML represents the same view structure and data binding as the C# declarative example, using Avalonia's XAML syntax with compiled bindings. ```xml