-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eaef2f0
commit e71755d
Showing
12 changed files
with
724 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[config] | ||
SCM_DO_BUILD_DURING_DEPLOYMENT=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"appService.zipIgnorePattern": [ | ||
"node_modules{,/**}", | ||
".vscode{,/**}" | ||
], | ||
"appService.defaultWebAppToDeploy": "/subscriptions/f706b20f-09d0-4fef-a2fc-629fa3973d06/resourceGroups/TestDocs/providers/Microsoft.Web/sites/avaloniauitestdocs", | ||
"appService.deploySubpath": "." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
sidebar_label: 'Namespaces!' | ||
sidebar_position: 0 | ||
--- | ||
|
||
# Namespaces | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Accessing the UI thread | ||
|
||
A `Dispatcher` provides services for managing work items on a specific thread. In Avalonia you will usually have only one `Dispatcher`, the one that handles the UI thread. Whenever you need to update the UI from a different thread than the UI thread, you need to access the UI thread via the running `Dispatcher`. | ||
|
||
## Access the UI thread from a different thread | ||
|
||
You can access the current UI thread via `Dispatcher.UIThread`. You can either use `Post` or `InvokeAsync`, if you want to run a job on the UI thread. Use `Post` when you just want to start a job, but you don't need to wait for the job to be finished and you don't need the result. If you need to wait for the result, then use `InvokeAsync` instead. | ||
|
||
## The DispatcherPriority | ||
|
||
The `DispatcherPriority` specifies at which priority the given job should be queued. For possible values please refer to the [API-Reference](http://reference.avaloniaui.net/api/Avalonia.Threading/DispatcherPriority/) | ||
|
||
## Examples | ||
|
||
In the below example we have a `TextBlock` which shows the result and a `Button` which is used to start our work. | ||
|
||
Our view looks like this: | ||
|
||
```markup | ||
<StackPanel> | ||
<TextBlock x:Name="TextBlock_Result" /> | ||
<Button Content="Run long running process" Click="Button_OnClick" /> | ||
</StackPanel> | ||
``` | ||
|
||
The long running task looks like this: | ||
|
||
```csharp | ||
async Task LongRunningTask() | ||
{ | ||
// Do some work | ||
this.FindControl<TextBlock>("TextBlock_Result").Text = "I'm working ..."; | ||
await Task.Delay(2000); | ||
this.FindControl<TextBlock>("TextBlock_Result").Text = "Done"; | ||
} | ||
``` | ||
|
||
Finally we can run the long running task as shown below: | ||
|
||
```csharp | ||
private void Button_OnClick(object sender, RoutedEventArgs e) | ||
{ | ||
// Start the job and return immediately | ||
Dispatcher.UIThread.Post(() => LongRunningTask(), DispatcherPriority.Background); | ||
} | ||
``` | ||
|
||
if we want to get the result to work with it further, we need to change the long running task to return the result: | ||
|
||
```csharp | ||
async Task<string> LongRunningTask() | ||
{ | ||
// Do some work | ||
this.FindControl<TextBlock>("TextBlock_Result").Text = "I'm working ..."; | ||
await Task.Delay(2000); | ||
this.FindControl<TextBlock>("TextBlock_Result").Text = "Done"; | ||
|
||
// return a result | ||
return "Success"; | ||
} | ||
``` | ||
|
||
We can use the result now: | ||
|
||
```csharp | ||
private async void Button_OnClick(object sender, RoutedEventArgs e) | ||
{ | ||
// Run the job | ||
var result = await Dispatcher.UIThread.InvokeAsync(LongRunningTask, DispatcherPriority.Background); | ||
|
||
// Work with the result | ||
Debug.WriteLine(result); | ||
} | ||
``` | ||
|
||
## Reference | ||
[Dispatcher](http://reference.avaloniaui.net/api/Avalonia.Threading/Dispatcher/) | ||
|
||
## Source Code | ||
[Dispatcher.cs](https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Base/Threading/Dispatcher.cs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
# 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: | ||
|
||
|
||
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. | ||
} | ||
} | ||
``` | ||
|
Oops, something went wrong.