Akbura's Visual Studio and VS Code extensions share the same project-aware
completion model. The model uses the current C# compilation, .akbura syntax,
and the Avalonia resource files included in the project.
x.DataType​
Inside an x.DataType value, completion suggests C# types rather than ordinary
string values. The editor understands the component's namespace, using and
global using directives, aliases, qualified names, and the type forms accepted
by the Akbura compiler. The completed value is also classified as a type.
<ItemsControl.ItemTemplate x.DataType="MyApp.Models.TaskItem">
<TextBlock Text=${CompiledBinding Title} />
</ItemsControl.ItemTemplate>
An explicit x.DataType supplies the receiver type for bindings inside the
template. Where Akbura can infer a template item type, binding completion uses
that inferred type instead.
Binding paths​
Path completion is available in Binding, CompiledBinding, and
ReflectionBinding, for both the first positional argument and Path=:
<TextBlock Text=${Binding Customer.DisplayName} />
<TextBlock Text=${CompiledBinding Path=Customer.DisplayName} />
Suggestions follow the type at the cursor, including inherited public
properties and the element type after supported indexers. Akbura also uses its
existing binding semantics for contexts such as $self, $parent, named
elements, casts, and template item scopes. Completion replaces only the path
segment being edited, so completing in the middle of a path does not duplicate
its prefix or suffix.
Expression bindings​
The editor offers the built-in x.bind directive in markup value prefixes,
including incomplete ${x. and ${x.bi input. After the directive, completion
uses embedded C# with the real component scope and target property type, not an
Avalonia BindingPath. Nested members, indexers, interpolation, locals and template
items use the normal scoped C# projection when project semantics are available.
The same services handle ${x.bind condition}:utility with a Boolean context.
The prefix and utility remain distinct from the embedded C# span. Shared
classification, hover, definition, references/rename and diagnostics map back to
the original .akbura text. Syntax-only prefix assistance does not imply that
semantic member completion works without a loaded project. Ordinary
${Binding ...} keeps its separate binding-path completion.
See Expression Bindings for the property and utility contracts, examples and observation limitations.
Resource keys​
StaticResource and DynamicResource offer the same set of resource keys:
<Border Background=${StaticResource CardBackgroundBrush} />
<Border BorderBrush=${DynamicResource AccentBrush} />
The editor combines resource declarations that are provably available from:
- the current
.akburaresource scopes; - local
.axamlfiles and their literal resource dictionary imports; - explicitly exported dictionaries in referenced assemblies; and
- a small catalog of known Avalonia built-in resource hints.
Keys remain case-sensitive and are inserted exactly as declared. Quoted keys,
spaces, dots, and hyphens are preserved. Local .axaml edits are read from the
open editor buffer, so adding or removing a resource or import can update
completion before the file is saved or the project is rebuilt.
Only .axaml files included by the evaluated project are indexed. A file that
merely exists beside the project, or under bin or obj, is not treated as an
application resource.
Exporting library resources​
A compiled library has no portable public API for enumerating its embedded Avalonia resources. A library can opt in to Akbura completion by adding assembly attributes for the keys it intentionally publishes:
using Akbura.CompilerAnotations;
using Avalonia.Media;
[assembly: ExportResourceForAkburaCompletion(
"Styles.axaml",
"CardBackgroundBrush",
typeof(SolidColorBrush))]
[assembly: ExportResourceForAkburaCompletion(
"Styles.axaml",
"AccentColor",
typeof(Color))]
[assembly: ExportResourceForAkburaCompletion(
"Themes/Compact.axaml",
"CompactSpacing",
typeof(double))]
dictionaryPath is relative to the resource root of the assembly carrying the
attribute. It is an assembly resource path, not a path relative to the solution,
consumer project, or source file. Use the exact published dictionary path, such
as Styles.axaml or Themes/Compact.axaml.
resourceType describes the actual resource value, or a correct public contract
for it. For example, export a SolidColorBrush resource as
typeof(SolidColorBrush) or typeof(IBrush), not as the type of a property that
might consume the brush. Do not infer a type from the spelling of the key.
Apply the attribute once for every exported key. A library may export multiple keys from one dictionary and separate sets from multiple dictionaries.
Imports activate exact exports​
Export metadata does not make every referenced library key globally visible. A consumer activates only the assembly and dictionary path that it imports:
<ResourceInclude Source="avares://Acme.Theme/Styles.axaml" />
This import activates the Styles.axaml exports on Acme.Theme. It does not
activate Themes/Compact.axaml, nor a Styles.axaml exported by another
assembly. Removing the last reachable import removes those suggestions.
If a package exposes a wrapper dictionary that imports dictionaries from other assemblies, the wrapper assembly must re-export the public keys under the wrapper's own entry-point path. Akbura does not guess transitive exports hidden behind a compiled wrapper:
[assembly: ExportResourceForAkburaCompletion(
"ThemePack.axaml",
"CardBackgroundBrush",
typeof(SolidColorBrush))]
The attribute must be present in the assembly used by the consumer's C#
compilation. NuGet packages that ship a compile/reference assembly under ref/
must preserve these assembly attributes there; putting them only in the runtime
assembly is not enough. Akbura reads symbols from the existing Roslyn
compilation and does not load the runtime assembly or inspect Avalonia's private
resource bundle format.
The attribute has no runtime behavior. It does not load a dictionary, create a resource, validate that a key exists, or change Avalonia lookup. Consumers must still import the real dictionary at runtime.
Known limitations​
- Built-in entries are editor hints, not proof that a key is present in the selected Avalonia theme at runtime.
- Only completed literal resource imports are followed. Bindings, markup
extensions, values assembled in code, and other computed
Sourcevalues are not executed by the editor. - When editing a shared library, Akbura does not guess which consuming
application's
Appshould supply global resources. - Complex selector-dependent scopes and custom resource containers are analyzed conservatively. A runtime-valid key may therefore be absent from completion.
- Conversely, normal runtime lookup rules still decide whether a suggested key is available at the point where the application executes.
Completion is assistance rather than a closed-world resource validator. An unknown key may still be supplied at runtime by code, a host application, a computed import, or another mechanism the editor intentionally does not run.