175 строки
5.8 KiB
Markdown
175 строки
5.8 KiB
Markdown
# Code-behind
|
|
|
|
[Window](https://docs.avaloniaui.net/docs/controls/window) and [UserControl](https://docs.avaloniaui.net/docs/controls/usercontrol) files also have an associated _code-behind_ file which usually has the extension `.xaml.cs` or `.axaml.cs` and may be displayed collapsed under the XAML file in your editor. Below you can see a `MainWindow.xaml` file along with its markdown file `MainWindow.xaml.cs` in Visual Studio:
|
|
|
|
![Code-behind in Visual Studio](../../.gitbook/assets/codebehind-vs.png)
|
|
|
|
The code-behind file by default defines a .NET class with the same name as your XAML file, e.g.
|
|
|
|
```csharp
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Markup.Xaml;
|
|
|
|
namespace AvaloniaApplication1
|
|
{
|
|
public class MainWindow : Window
|
|
{
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
#if DEBUG
|
|
AttachDevTools();
|
|
#endif
|
|
}
|
|
|
|
private void InitializeComponent()
|
|
{
|
|
AvaloniaXamlLoader.Load(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
```
|
|
|
|
Note that this class definition corresponds closely to the XAML file:
|
|
|
|
```markup
|
|
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
x:Class="AvaloniaApplication1.MainWindow">
|
|
</Window>
|
|
```
|
|
|
|
* The base class, `Window` is the root element of the XAML file
|
|
* The `x:Class` attribute references the fully-qualified name of the class defined in code-behind
|
|
|
|
If you make any changes to the base class, namespace, or name of the class, make sure to update both the code-behind and the XAML to ensure they match.
|
|
|
|
In addition, the class contains two more things of interest:
|
|
|
|
* It enables [DevTools](https://docs.avaloniaui.net/docs/getting-started/developer-tools) in debug mode
|
|
* It defines an `InitializeComponent` method which is used to load the XAML at runtime
|
|
|
|
### Locating Controls <a id="locating-controls"></a>
|
|
|
|
One of the main uses of the code-behind file is to manipulate controls using C\# code. To do this you'll usually first want to get a reference to a named control. This can be done using the `FindControl<T>` method:
|
|
|
|
```markup
|
|
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
x:Class="AvaloniaApplication4.MainWindow">
|
|
<Button Name="myButton">Hello World</Button>
|
|
</Window>
|
|
```
|
|
|
|
```csharp
|
|
public class MainWindow : Window
|
|
{
|
|
private Button myButton;
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
#if DEBUG
|
|
AttachDevTools();
|
|
#endif
|
|
}
|
|
|
|
private void InitializeComponent()
|
|
{
|
|
AvaloniaXamlLoader.Load(this);
|
|
myButton = this.FindControl<Button>("myButton");
|
|
}
|
|
}
|
|
```
|
|
|
|
`FindControl` must be called after `AvaloniaXamlLoader.Load` has run because it's not until this point that the control will have been created.
|
|
|
|
The good news this step is not necessary if you're using [Avalonia.NameGenerator](https://github.com/AvaloniaUI/Avalonia.NameGenerator) package (added to the Avalonia templates by default), because it provides a code-generation step which creates this code for you.
|
|
In such case the code-behind class can be simplified to:
|
|
|
|
```csharp
|
|
public partial class MainWindow : Window
|
|
{
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
}
|
|
```
|
|
|
|
Note the class is now declared as `partial`. That's because all the boilerplate code is now auto-generated by the Avalonia.NameGenerator at the second partial class which is not visible in the project.
|
|
For the given XAML, it will look like follows:
|
|
|
|
```csharp
|
|
// <auto-generated />
|
|
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Markup.Xaml;
|
|
|
|
namespace AvaloniaApplication1
|
|
{
|
|
partial class MainWindow
|
|
{
|
|
internal global::Avalonia.Controls.Button myButton;
|
|
|
|
/// <summary>
|
|
/// Wires up the controls and optionally loads XAML markup and attaches dev tools (if Avalonia.Diagnostics package is referenced).
|
|
/// </summary>
|
|
/// <param name="loadXaml">Should the XAML be loaded into the component.</param>
|
|
/// <param name="attachDevTools">Should the dev tools be attached.</param>
|
|
public void InitializeComponent(bool loadXaml = true, bool attachDevTools = true)
|
|
{
|
|
if (loadXaml)
|
|
{
|
|
AvaloniaXamlLoader.Load(this);
|
|
}
|
|
|
|
#if DEBUG
|
|
if (attachDevTools)
|
|
{
|
|
this.AttachDevTools();
|
|
}
|
|
#endif
|
|
|
|
myButton = this.FindControl<global::Avalonia.Controls.Button>("myButton");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
The auto-generated `InitializeComponent` has arguments to optionally call the `AvaloniaXamlLoader.Load(this)` and `AttachDevTools`, so you don't need to call them yourself from your code-behind class anymore.
|
|
Never keep a method named `InitializeComponent` in your code-behind view class if you are using the generator with default settings. Read more at the [Avalonia.NameGenerator documentation](https://github.com/AvaloniaUI/Avalonia.NameGenerator#advanced-usage).
|
|
|
|
For the rest of the documentation, we'll assume you're either using Avalonia templates or added the Avalonia.NameGenerator package to your project manually.
|
|
|
|
### Handling Events <a id="handling-events"></a>
|
|
|
|
Another common use for the code-behind file is to define _event handlers_. Event handlers are defined as methods in the code-behind and referenced from XAML. For example to add a handler for a button click:
|
|
|
|
```markup
|
|
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
x:Class="AvaloniaApplication4.MainWindow">
|
|
<Button Click="MyButton_Click">Hello World</Button>
|
|
</Window>
|
|
```
|
|
|
|
```csharp
|
|
public partial class MainWindow : Window
|
|
{
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public void MyButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
// Handle click here.
|
|
}
|
|
}
|
|
```
|
|
|