GitBook: [master] 21 pages and 2 assets modified

This commit is contained in:
Maksym Katsydan 2021-07-01 23:11:01 +00:00 коммит произвёл gitbook-bot
Родитель 219c12e0c5
Коммит 223806f9db
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 07D2180C7B12D0FF
22 изменённых файлов: 128 добавлений и 130 удалений

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.2 KiB

После

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Просмотреть файл

@ -5,7 +5,7 @@ There are two types of animations in Avalonia:
* [Keyframe animations](keyframe-animations.md) animate any number of properties on a control, using any number of keyframes to define the states that each property must pass through. Keyframe animations are the more versatile type of animation.
* [Transitions](transitions.md) are used to animate a single property change.
### In This Section <a id="in-this-section"></a>
## In This Section <a id="in-this-section"></a>
* [Keyframe Animations](keyframe-animations.md)
* [Transitions](transitions.md)

Просмотреть файл

@ -2,7 +2,7 @@
Keyframe animations in Avalonia are heavily inspired by CSS Animations. They can be used to animate any number of properties on a control, using any number of keyframes to define the states that each property must pass through. Keyframe animations can run any number of times, in either direction.
### Defining A Keyframe Animation <a id="defining-a-keyframe-animation"></a>
## Defining A Keyframe Animation <a id="defining-a-keyframe-animation"></a>
Keyframe animations are applied using styles. They can be defined on any style by adding an `Animation` object to the `Style.Animation` property:
@ -32,13 +32,13 @@ Keyframe animations are applied using styles. They can be defined on any style b
The example above animates the target `Control` as defined by its [selector](https://docs.avaloniaui.net/docs/styling/selectors). It will be run immediately when the control is loaded.
### Triggering Animations <a id="triggering-animations"></a>
## Triggering Animations <a id="triggering-animations"></a>
Unlike WPF's `Triggers`, Animations defined in XAML rely on [selectors](https://docs.avaloniaui.net/docs/styling/selectors) for their triggering behavior. Selectors can always apply to a control, or they can conditionally apply \(for example if the control has a style class appled\).
If the selector isn't conditional then the animation will be triggered when a matching `Control` is spawned into the visual tree. Otherwise, the animations will run whenever its selector is activated. When the selector no longer matches, the currently running animation will be canceled.
### `KeyFrames` <a id="keyframes"></a>
## `KeyFrames` <a id="keyframes"></a>
The `KeyFrame` objects defines when the target `Setter` objects should be applied on the target `Control`, with value interpolation in-between.
@ -61,7 +61,7 @@ Multiple properties can be also animated in a single Animation by adding additio
</Animation>
```
### Delay <a id="delay"></a>
## Delay <a id="delay"></a>
You can add a delay in a `Animation` by defining the desired delay time on its `Delay` property:
@ -72,7 +72,7 @@ You can add a delay in a `Animation` by defining the desired delay time on its `
</Animation>
```
### Repeat <a id="repeat"></a>
## Repeat <a id="repeat"></a>
You can set the following repeat behaviors on `IterationCount` property of an `Animation`.
@ -81,7 +81,7 @@ You can set the following repeat behaviors on `IterationCount` property of an `A
| `0` to N | Play N times. |
| `INFINITE` | Repeat Indefinitely |
### Playback Direction <a id="playback-direction"></a>
## Playback Direction <a id="playback-direction"></a>
The `PlaybackDirection` property defines how should the animation be played, including repeats.
@ -94,7 +94,7 @@ The following table describes the possible behaviors:
| `Alternate` | The animation is played forwards first, then backwards. |
| `AlternateReverse` | The animation is played backwards first, then forwards. |
### Value fill modes <a id="value-fill-modes"></a>
## Value fill modes <a id="value-fill-modes"></a>
The `FillMode` property defines whether the first or last interpolated value of an animation persist before or after running an animation and on delays in-between runs.
@ -107,7 +107,7 @@ The following table describes the possible behaviors:
| `Backward` | The first interpolated value will be displayed on animation delay. |
| `Both` | Both `Forward` and `Backward` behaviors will be applied. |
### Easings <a id="easings"></a>
## Easings <a id="easings"></a>
Easing functions can be set by setting the name of the desired function to the `Animation`'s `Easing` property:

Просмотреть файл

@ -95,7 +95,7 @@ We can display the student's first and last name in a `ContentControl` using the
</Window>
```
![Student first and last name](../../.gitbook/assets/student-first-last-name%20%281%29.png)
![Student first and last name](../../.gitbook/assets/student-first-last-name%20%281%29%20%281%29.png)
For more information see the [data templates](http://avaloniaui.net/docs/templates/datatemplate) section.

Просмотреть файл

@ -2,17 +2,17 @@
The `TextBox` control is an editable text field where a user can input text.
### Reference <a id="reference"></a>
## Reference <a id="reference"></a>
[TextBox](http://reference.avaloniaui.net/api/Avalonia.Controls/TextBox/)
### Source code <a id="source-code"></a>
## Source code <a id="source-code"></a>
[TextBox.cs](https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Controls/TextBox.cs)
### Examples <a id="examples"></a>
## Examples <a id="examples"></a>
#### Basic one line TextBox <a id="basic-one-line-textbox"></a>
### Basic one line TextBox <a id="basic-one-line-textbox"></a>
```markup
<Window xmlns="https://github.com/avaloniaui"
@ -22,18 +22,17 @@ The `TextBox` control is an editable text field where a user can input text.
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaAppTemplate.MainWindow"
Title="AvaloniaAppTemplate">
<StackPanel Margin="10">
<TextBox />
</StackPanel>
<StackPanel Margin="10">
<TextBox />
</StackPanel>
</Window>
```
produces the following output in **Windows 10**
produces the following output in **Windows 10**
![](../../.gitbook/assets/textbox_basic.png)
#### Password input TextBox <a id="password-input-textbox"></a>
### Password input TextBox <a id="password-input-textbox"></a>
```markup
<Window xmlns="https://github.com/avaloniaui"
@ -43,18 +42,17 @@ produces the following output in **Windows 10**
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaAppTemplate.MainWindow"
Title="AvaloniaAppTemplate">
<StackPanel Margin="10">
<TextBox PasswordChar="#" />
</StackPanel>
<StackPanel Margin="10">
<TextBox PasswordChar="#" />
</StackPanel>
</Window>
```
produces the following output in **Windows 10** when text is input
produces the following output in **Windows 10** when text is input
![](../../.gitbook/assets/textbox_password.png)
#### TextBox with watermark <a id="textbox-with-watermark"></a>
### TextBox with watermark <a id="textbox-with-watermark"></a>
Avalonia can show a "watermark" in a `TextBox`, which is a piece of text that is displayed when the `TextBox` is empty \(in HTML5 this is called a _placeholder_\)
@ -66,18 +64,17 @@ Avalonia can show a "watermark" in a `TextBox`, which is a piece of text that is
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaAppTemplate.MainWindow"
Title="AvaloniaAppTemplate">
<StackPanel Margin="10">
<TextBox Watermark="Street address" />
</StackPanel>
<StackPanel Margin="10">
<TextBox Watermark="Street address" />
</StackPanel>
</Window>
```
produces the following output in **Windows 10**
produces the following output in **Windows 10**
![](../../.gitbook/assets/textbox_watermark.png)
#### Multiline TextBox <a id="multiline-textbox"></a>
### Multiline TextBox <a id="multiline-textbox"></a>
```markup
<Window xmlns="https://github.com/avaloniaui"
@ -87,23 +84,25 @@ produces the following output in **Windows 10**
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaAppTemplate.MainWindow"
Title="AvaloniaAppTemplate">
<Grid Margin="10">
<TextBox AcceptsReturn="True" TextWrapping="Wrap" />
</Grid>
<Grid Margin="10">
<TextBox AcceptsReturn="True" TextWrapping="Wrap" />
</Grid>
</Window>
```
produces the following output in **Windows 10** when text is input
produces the following output in **Windows 10** when text is input
![](../../.gitbook/assets/textbox_multiline.png)
#### TextInput Event Handling <a id="textinput-event-handling"></a>
### TextInput Event Handling <a id="textinput-event-handling"></a>
By default the TextInput event does nothing if you assign directly to it. This is due to the TextBox itself handling the event from the underlying InputElement.
By default the [TextInput](http://reference.avaloniaui.net/api/Avalonia.Input/InputElement/37F81F6F) event does nothing if you assign directly to it. This is due to the TextBox itself handling the event from the underlying InputElement.
If you wish to access the TextInput event, then you will have to use the TextBox.AddHandler method to intercept the event via event tunneling.
```code
```csharp
MyTextInput.AddHandler(TextInputEvent, MyTextInput_InputHandler, RoutingStrategies.Tunnel);
```
To see more details about this behavior, read [routed events](../input/routed-events.md) documentation page.

Просмотреть файл

@ -2,7 +2,7 @@
Binding from code in Avalonia works somewhat differently to WPF/UWP. At the low level, Avalonia's binding system is based on Reactive Extensions' `IObservable` which is then built upon by XAML bindings \(which can also be instantiated in code\).
### Subscribing to Changes to a Property <a id="subscribing-to-changes-to-a-property"></a>
## Subscribing to Changes to a Property <a id="subscribing-to-changes-to-a-property"></a>
You can subscribe to changes on a property by calling the `GetObservable` method. This returns an `IObservable<T>` which can be used to listen for changes to the property:
@ -27,7 +27,7 @@ When the returned observable is subscribed, it will return the current value of
var text = textBlock.GetObservable(TextBlock.TextProperty).Skip(1);
```
### Binding to an observable <a id="binding-to-an-observable"></a>
## Binding to an observable <a id="binding-to-an-observable"></a>
You can bind a property to an observable using the `AvaloniaObject.Bind` method:
@ -50,7 +50,7 @@ subscription.Dispose();
Notice that the `Bind` method returns an `IDisposable` which can be used to terminate the binding. If you never call this, then then binding will automatically terminate when the observable finishes via `OnCompleted` or `OnError`.
### Setting a binding in an object initializer <a id="setting-a-binding-in-an-object-initializer"></a>
## Setting a binding in an object initializer <a id="setting-a-binding-in-an-object-initializer"></a>
It is often useful to set up bindings in object initializers. You can do this using the indexer:
@ -84,7 +84,7 @@ textBlock2[!TextBlock.TextProperty] = textBlock1[!TextBlock.TextProperty];
The only downside of this syntax is that no `IDisposable` is returned. If you need to manually terminate the binding then you should use the `Bind` method.
### Transforming binding values <a id="transforming-binding-values"></a>
## Transforming binding values <a id="transforming-binding-values"></a>
Because we're working with observables, we can easily transform the values we're binding!
@ -98,7 +98,7 @@ var textBlock = new TextBlock
};
```
### Using XAML bindings from code <a id="using-xaml-bindings-from-code"></a>
## Using XAML bindings from code <a id="using-xaml-bindings-from-code"></a>
Sometimes when you want the additional features that XAML bindings provide, it's easier to use XAML bindings from code. For example, using only observables you could bind to a property on `DataContext` like this:
@ -128,7 +128,7 @@ var subscription = textBlock.Bind(TextBlock.TextProperty, new Binding("Name"));
subscription.Dispose();
```
### Subscribing to a Property on Any Object <a id="subscribing-to-a-property-on-any-object"></a>
## Subscribing to a Property on Any Object <a id="subscribing-to-a-property-on-any-object"></a>
The `GetObservable` method returns an observable that tracks changes to a property on a single instance. However, if you're writing a control you may want to implement an `OnPropertyChanged` method which isn't tied to an instance of an object.

Просмотреть файл

@ -32,7 +32,7 @@ namespace Example
</Window>
```
### CommandParameter <a id="commandparameter"></a>
## CommandParameter <a id="commandparameter"></a>
You can also pass a parameter to the command using the `CommandParameter` property:
@ -78,9 +78,9 @@ Note that no type conversion is carried out on `CommandParameter`, so if you nee
Like any other property, `CommandParameter` can also be bound.
### Binding To Methods <a id="binding-to-methods"></a>
## Binding To Methods <a id="binding-to-methods"></a>
#### ICommand.Execute <a id="icommandexecute"></a>
### ICommand.Execute <a id="icommandexecute"></a>
Sometimes you just want to call a method when a button is clicked without the ceremony of creating a command. You can do that too!
@ -103,7 +103,7 @@ namespace Example
</Window>
```
#### ICommand.CanExecute <a id="icommandcanexecute"></a>
### ICommand.CanExecute <a id="icommandcanexecute"></a>
If you need to have execution dependent on CommandParameter or your ViewModel property, you can define a named method formed by the prefix "Can" and the name of your execution method; the method will accept an object parameter which is the CommandParameter and return a Boolean which determines if the method is executable.

Просмотреть файл

@ -1,12 +1,12 @@
# Binding to Controls
As well as binding to a control's [`DataContext`](https://docs.avaloniaui.net/docs/data-binding/the-datacontext) you can also bind to other controls.
As well as binding to a control's [`DataContext`](https://docs.avaloniaui.net/docs/data-binding/the-datacontext) you can also bind to other controls.
{% hint style="info" %}
Note that when you do this, the binding source is to the _control itself_ not the control's `DataContext`. If you want to bind to the control's `DataContext` then you'll need to specify that in the binding path.
Note that when you do this, the binding source is to the _control itself_ not the control's `DataContext`. If you want to bind to the control's `DataContext` then you'll need to specify that in the binding path.
{% endhint %}
### Binding to a named control
## Binding to a named control
If you want to bind to a property on another named control, you can use the control name prefixed by a `#` character.
@ -26,7 +26,7 @@ This is the equivalent to the long-form binding that will be familiar to WPF and
Avalonia supports both syntaxes but the short-form `#` syntax is less verbose.
### Binding to an Ancestor <a id="binding-to-an-ancestor"></a>
## Binding to an Ancestor <a id="binding-to-an-ancestor"></a>
You can bind to the logical parent of the target using the `$parent` symbol:
@ -81,6 +81,6 @@ If you need to include a XAML namespace in the ancestor type, you can do that us
```
{% hint style="warning" %}
Avalonia also supports WPF/UWP's `RelativeSource` syntax which does something similar, but is _not_ the same. `RelativeSource` works on the _visual_ tree whereas the syntax given here works on the _logical_ tree.
Avalonia also supports WPF/UWP's `RelativeSource` syntax which does something similar, but is _not_ the same. `RelativeSource` works on the _visual_ tree whereas the syntax given here works on the _logical_ tree.
{% endhint %}

Просмотреть файл

@ -24,7 +24,7 @@ An empty binding binds to DataContext itself
We call the property on the control the binding _target_ and the property on the `DataContext` the binding _source_.
### Binding Path <a id="binding-path"></a>
## Binding Path <a id="binding-path"></a>
The binding path above can be a single property, or it can be a chain of properties. For example if the object assigned to the `DataContext` has a `Student` property, and the value of this property has a `Name`, you can bind to the student name using:
@ -38,7 +38,7 @@ You can also include array/list indexers in binding paths:
<TextBlock Text="{Binding Students[0].Name}"/>
```
### Binding Modes <a id="binding-modes"></a>
## Binding Modes <a id="binding-modes"></a>
You can change the behavior of a `{Binding}` by specifing a binding `Mode`:
@ -56,5 +56,5 @@ The available binding modes are:
| `OneWayToSource` | Changes to the target are propagated to the source |
| `Default` | The binding mode is based on the property |
The `Default` mode is assumed if one is not specified. This mode is generally `OneWay` for control properties that do not change due to user input \(e.g. `TextBlock.Text`\) and `TwoWay` for control properties that _do_ change due to user input \(e.g. `TextBox.Text`\).
The `Default` mode is assumed if one is not specified. This mode is generally `OneWay` for control properties that do not change due to user input \(e.g. `TextBlock.Text`\) and `TwoWay` for control properties that _do_ change due to user input \(e.g. `TextBox.Text`\).

Просмотреть файл

@ -28,7 +28,7 @@ This means that when the `MainWindow` is created, a new instance of `MainWindowV
Will bind the `Button`'s `Content` to `Window.DataContext.ButtonCaption`.
### Binding DataContext <a id="binding-datacontext"></a>
## Binding DataContext <a id="binding-datacontext"></a>
When binding `DataContext`, the `DataContext` of the parent control is used as the source of the binding:

Просмотреть файл

@ -2,7 +2,7 @@
Avalonia lets you develop an appliction using the [XAML markup language](https://docs.avaloniaui.net/guides/basics/introduction-to-xaml) and C\# \(or another .NET language\) for code. You generally use XAML markup to implement the appearance of an application while using code to implement its behavior.
### Markup
## Markup
XAML is an XML-based markup language that implements an application's appearance declaratively. You typically use it to create windows and user controls, and to fill them with controls, shapes, and graphics.
@ -14,7 +14,7 @@ The following example uses XAML to implement the appearance of a window that con
x:Class="AvaloniaApplication1.MainWindow"
Title="Window with Button"
Width="250" Height="100">
<!-- Add button to window -->
<Button Name="button">Click Me!</Button>
@ -29,7 +29,7 @@ Since XAML is XML-based, the UI that you compose with it is assembled in a hiera
![](../../../.gitbook/assets/click-me.png)
### Code-behind
## Code-behind
The main behavior of an application is to implement the functionality that responds to user interactions, including handling events \(for example, clicking a menu, tool bar, or button\) and calling business logic and data access logic in response. In Avalonia, this behavior can be implemented in code that is associated with markup. This type of code is known as [code-behind](https://docs.avaloniaui.net/guides/basics/code-behind). The following example shows the updated markup from the previous example and the code-behind:
@ -41,7 +41,7 @@ The main behavior of an application is to implement the functionality that respo
x:Class="AvaloniaApplication1.MainWindow"
Title="Window with Button"
Width="250" Height="100">
<!-- Add button to window -->
<Button Name="button" Click="button_Click">Click Me!</Button>

Просмотреть файл

@ -1,6 +1,6 @@
# Graphics & Animations
### Graphics
## Graphics
Avalonia introduces an extensive, scalable, and flexible set of graphics features that have the following benefits:
@ -9,7 +9,7 @@ Avalonia introduces an extensive, scalable, and flexible set of graphics feature
* Advanced graphics and animation support. Avalonia simplifies graphics programming by managing animation scenes for you; there is no need to worry about scene processing, rendering loops, and bilinear interpolation. Additionally, Avalonia provides hit-testing support and full alpha-compositing support.
* Skia. By default Avalonia uses the [Skia rendering engine](https://skia.org/), the same rendering engine that powers Google Chrome and Chrome OS, Android, Mozilla Firefox and Firefox OS, and many other products.
### 2D Shapes and Geometries
## 2D Shapes and Geometries
Avalonia provides a library of common vector-drawn 2D shapes such as `Ellipse`, `Line`, `Path`, `Polygon` and `Rectangle`.
@ -47,7 +47,7 @@ Avalonia provides a library of common vector-drawn 2D shapes such as `Ellipse`,
![](../../../.gitbook/assets/shapes.png)
### Animation
## Animation
Avalonia's animation support lets you make controls grow, shake, spin, and fade, to create interesting page transitions, and more. Avalonia uses a CSS-like animation system which supports [property transitions](https://docs.avaloniaui.net/docs/animations/transitions) and [keyframe animations](https://docs.avaloniaui.net/docs/animations/keyframe-animations).

Просмотреть файл

@ -1,6 +1,6 @@
# 📐 Layout
### Panels <a id="panels"></a>
## Panels <a id="panels"></a>
Avalonia includes a group of elements that derive from `Panel`. These `Panel` elements enable many complex layouts. For example, stacking elements can easily be achieved by using the `StackPanel` element, while more complex and free flowing layouts are possible by using a `Canvas`.
@ -18,11 +18,11 @@ The following table summarizes the available `Panel` controls:
In WPF, `Panel` is an abstract class and laying out multiple controls to fill the available space is usually done with a `Grid` with no rows/columns. In Avalonia `Panel` is a usable control that has the same layout behavior as a `Grid` with no rows/columns, but with a lighter runtime footprint.
### Element Bounding Boxes <a id="element-bounding-boxes"></a>
## Element Bounding Boxes <a id="element-bounding-boxes"></a>
When thinking about layout in Avalonia, it is important to understand the bounding box that surrounds all elements. Each `Control` consumed by the layout system can be thought of as a rectangle that is slotted into the layout. The `Bounds` property returns the boundaries of an element's layout allocation. The size of the rectangle is determined by calculating the available screen space, the size of any constraints, layout-specific properties \(such as margin and padding\), and the individual behavior of the parent `Panel` element. Processing this data, the layout system is able to calculate the position of all the children of a particular `Panel`. It is important to remember that sizing characteristics defined on the parent element, such as a `Border`, affect its children.
### The Layout System <a id="the-layout-system"></a>
## The Layout System <a id="the-layout-system"></a>
At its simplest, layout is a recursive system that leads to an element being sized, positioned, and drawn. More specifically, layout describes the process of measuring and arranging the members of a `Panel` element's `Children` collection. Layout is an intensive process. The larger the `Children` collection, the greater the number of calculations that must be made. Complexity can also be introduced based on the layout behavior defined by the `Panel` element that owns the collection. A relatively simple `Panel`, such as `Canvas`, can have significantly better performance than a more complex `Panel`, such as `Grid`.
@ -37,7 +37,7 @@ Each time that a child control changes its position, it has the potential to tri
This process and how it is invoked are defined in more detail in the following sections.
### Measuring and Arranging Children <a id="measuring-and-arranging-children"></a>
## Measuring and Arranging Children <a id="measuring-and-arranging-children"></a>
The layout system completes two passes for each member of the `Children` collection, a measure pass and an arrange pass. Each child `Panel` provides its own `MeasureOverride` and `ArrangeOverride` methods to achieve its own specific layout behavior.
@ -55,9 +55,9 @@ The arrange pass begins with a call to the `Arrange` method. During the arrange
The `ArrangeCore` method evaluates the `DesiredSize` of the child and evaluates any additional margins that may affect the rendered size of the element. `ArrangeCore` generates an arrange size, which is passed to the `ArrangeOverride` method of the `Panel` as a parameter. `ArrangeOverride` generates the finalSize of the child. Finally, the `ArrangeCore` method does a final evaluation of offset properties, such as margin and alignment, and puts the child within its layout slot. The child does not have to \(and frequently does not\) fill the entire allocated space. Control is then returned to the parent `Panel` and the layout process is complete.
### In This Section <a id="in-this-section"></a>
## In This Section <a id="in-this-section"></a>
* [Panels Overview](./panels-overview.md)
* [Alignment, Margins and Padding](./alignment-margins-and-padding.md)
* [Create a Custom Panel](./create-a-custom-panel.md)
* [Panels Overview](panels-overview.md)
* [Alignment, Margins and Padding](alignment-margins-and-padding.md)
* [Create a Custom Panel](create-a-custom-panel.md)

Просмотреть файл

@ -2,15 +2,15 @@
`Panel` elements are components that control the rendering of elements - their size and dimensions, their position, and the arrangement of their child content. Avalonia provides a number of predefined `Panel` elements as well as the ability to construct custom `Panel` elements.
### The Panel Class <a id="the-panel-class"></a>
## The Panel Class <a id="the-panel-class"></a>
`Panel` is the base class for all elements that provide layout support in Avalonia. Derived `Panel` elements are used to position and arrange elements in XAML and code.
Avalonia includes a comprehensive suite of derived panel implementations that enable many complex layouts. These derived classes expose properties and methods that enable most standard UI scenarios. Developers who are unable to find a child arrangement behavior that meets their needs can create new layouts by overriding the `ArrangeOverride` and `MeasureOverride` methods. For more information on custom layout behaviors, see [Create a Custom Panel](./create-a-custom-panel.md).
Avalonia includes a comprehensive suite of derived panel implementations that enable many complex layouts. These derived classes expose properties and methods that enable most standard UI scenarios. Developers who are unable to find a child arrangement behavior that meets their needs can create new layouts by overriding the `ArrangeOverride` and `MeasureOverride` methods. For more information on custom layout behaviors, see [Create a Custom Panel](create-a-custom-panel.md).
#### Panel Common Members <a id="panel-common-members"></a>
### Panel Common Members <a id="panel-common-members"></a>
All `Panel` elements support the base sizing and positioning properties defined by `Control`, including `Height`, `Width`, `HorizontalAlignment`, `VerticalAlignment` and `Margin`. For additional information on positioning properties defined by `Control`, see [Alignment, Margins, and Padding Overview](./alignment-margins-and-padding.md).
All `Panel` elements support the base sizing and positioning properties defined by `Control`, including `Height`, `Width`, `HorizontalAlignment`, `VerticalAlignment` and `Margin`. For additional information on positioning properties defined by `Control`, see [Alignment, Margins, and Padding Overview](alignment-margins-and-padding.md).
`Panel` exposes additional properties that are of critical importance in understanding and using layout. The `Background` property is used to fill the area between the boundaries of a derived panel element with a `Brush`. `Children` represents the child collection of elements that the `Panel` is comprised of.
@ -20,7 +20,7 @@ Derived panel elements make extensive use of attached properties. An attached pr
One purpose of an attached property is to allow child elements to store unique values of a property that is actually defined by a parent element. An application of this functionality is having child elements inform the parent how they wish to be presented in the UI, which is extremely useful for application layout.
#### User Interface Panels <a id="user-interface-panels"></a>
### User Interface Panels <a id="user-interface-panels"></a>
There are several panel classes available in Avalonia that are optimized to support UI scenarios: `Panel`, `Canvas`, `DockPanel`, `Grid`, `StackPanel`, `WrapPanel` and `RelativePanel`. These panel elements are easy to use, versatile, and extensible enough for most applications.
@ -331,7 +331,7 @@ myButton3.Content = "Button 3";
// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myStackPanel.Children.Add(myButton3);
myStackPanel.Children.Add(myButton3);
```
**WrapPanel**
@ -370,7 +370,7 @@ btn4.Width = 75;
myWrapPanel.Children.Add(btn1);
myWrapPanel.Children.Add(btn2);
myWrapPanel.Children.Add(btn3);
myWrapPanel.Children.Add(btn4);
myWrapPanel.Children.Add(btn4);
```
XAML
@ -383,10 +383,10 @@ XAML
<Button>Button 3</Button>
<Button>Button 4</Button>
</WrapPanel>
</Border>
</Border>
```
#### Nested Panel Elements <a id="nested-panel-elements"></a>
### Nested Panel Elements <a id="nested-panel-elements"></a>
`Panel` elements can be nested within each other in order to produce complex layouts. This can prove very useful in situations where one `Panel` is ideal for a portion of a UI, but may not meet the needs of a different portion of the UI.

Просмотреть файл

@ -1,6 +1,6 @@
# 🎨 Styling
[Styles in Avalonia](./styles.md) are used to share property settings between controls. The Avalonia styling system can be thought of as a mix of CSS styling and WPF/UWP styling. At its most basic, a style consists of a _selector_ and a collection of _setters_.
[Styles in Avalonia](styles.md) are used to share property settings between controls. The Avalonia styling system can be thought of as a mix of CSS styling and WPF/UWP styling. At its most basic, a style consists of a _selector_ and a collection of _setters_.
The following style selects any `TextBlock` in the `Window` with a `h1` _style class_ and sets its font size to 24 point and font weight to bold:

Просмотреть файл

@ -2,7 +2,7 @@
Often, styles and controls will need to share resources such as \(but not limited to\) brushes and colors. You can put such resources in the `Resources` dictionary which is available on every style and control and then refer to these resources elsewhere.
### Declaring resources <a id="declaring-resources"></a>
## Declaring resources <a id="declaring-resources"></a>
If a resource is to be available to your entire application, you can define it in `App.xaml`/`App.axaml`:
@ -52,7 +52,7 @@ You can also declare resources on styles:
</Style>
```
### Referencing resources <a id="referencing-resources"></a>
## Referencing resources <a id="referencing-resources"></a>
You can references resources from controls using the `{DynamicResource}` markup extensions, e.g.:
@ -69,7 +69,7 @@ Alternatively there is the `StaticResource` markup extension which has a few lim
In return, `StaticResource` doesn't need to add an event handler to listen for changes in resources which means it uses slightly less memory.
### Overriding resources <a id="overriding-resources"></a>
## Overriding resources <a id="overriding-resources"></a>
Resources are resolved by walking up the logical tree from the point of the `DynamicResource` or `StaticResource` until a resource with the requested key is found. This means that resources can be "overridden" in sub-trees of the application, for example:
@ -95,7 +95,7 @@ Resources are resolved by walking up the logical tree from the point of the `Dyn
Here's the `Border`'s background will be `Orange` because its parent `StackPanel` has "overridden" the `Warning` resource from the `Yellow` declared on the `UserControl`.
### Merged resource dictionaries <a id="merged-resource-dictionaries"></a>
## Merged resource dictionaries <a id="merged-resource-dictionaries"></a>
The `Resources` property on each control and style is of type `ResourceDictionary`. Resource dictionaries can also include other resource dictionaries by making use of the `MergedDictionaries` property. To include a resource dictionary in another you can use the `ResourceInclude` class, e.g.:
@ -112,7 +112,7 @@ The `Resources` property on each control and style is of type `ResourceDictionar
Where `AnotherResourceDictionary` is a XAML file with a root of `ResourceDictionary` and is included as an [asset](../getting-started/assets.md) in the application.
### Resource resolution <a id="resource-resolution"></a>
## Resource resolution <a id="resource-resolution"></a>
As mentioned above, resources are resolved by walking up the logical tree from the point of the `DynamicResource` or `StaticResource` until a resource with the requested key is found. However the presence of styles and merged dictionaries complicates this somewhat. The precedence is as follows:
@ -150,7 +150,7 @@ Window
|- Border
```
### Theme resources <a id="theme-resources"></a>
## Theme resources <a id="theme-resources"></a>
Themes will usually define brushes, colors and other settings as resources. By changing these resources one can e.g. switch from a dark to a light theme. The resources defined will usually be specific to the theme in use but you can see the resources defined by the default theme [here](https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Default/Accents/BaseLight.xaml).

Просмотреть файл

@ -1,6 +1,6 @@
# Selectors
### OfType <a id="oftype"></a>
## OfType <a id="oftype"></a>
{% tabs %}
{% tab title="XAML" %}
@ -20,11 +20,11 @@ new Style(x => x.OfType(typeof(Button)));
Selects a control by type. The first example above selects the `Avalonia.Controls.Button` class. To include a XAML namespace in the type separate the namespace and the type with a `|` character.
This selector does not match derived types. For that, use the [`Is`](#is) selector.
This selector does not match derived types. For that, use the [`Is`](selectors.md#is) selector.
> Note the type of an object is actually determined by looking at its IStyleable.StyleKey property. By default this simply returns the type of the current instance, but if, for example, you do want your control which inherits from `Button` to be styled as a `Button`, then you can implement the `IStyleable.StyleKey` property on your class to return `typeof(Button)`.
### Name <a id="name"></a>
## Name <a id="name"></a>
{% tabs %}
{% tab title="XAML" %}
@ -44,7 +44,7 @@ new Style(x => x.OfType<Button>().Name("myButton"));
Selects a control by its [`Name`](http://reference.avaloniaui.net/api/Avalonia/StyledElement/2362746E) property.
### Class <a id="class"></a>
## Class <a id="class"></a>
{% tabs %}
{% tab title="XAML" %}
@ -64,7 +64,7 @@ new Style(x => x.OfType<Button>().Class("large").Class(":focus"));
Selects a control with the specified style classes. Multiple classes should be separated with a `.` character, or a `:` character in the case of pseudoclasses. If multiple classes are specified then the control must have all of the requested classes present in order to match.
### Is <a id="is"></a>
## Is <a id="is"></a>
{% tabs %}
{% tab title="XAML" %}
@ -82,11 +82,11 @@ new Style(x => x.Is(typeof(Button)));
{% endtab %}
{% endtabs %}
This is very similar to the [`OfType`](#ofType) selector except it also matches derived types.
This is very similar to the [`OfType`](selectors.md#ofType) selector except it also matches derived types.
> Again, the type of an object is actually determined by looking at its IStyleable.StyleKey property.
### Child <a id="child"></a>
## Child <a id="child"></a>
{% tabs %}
{% tab title="XAML" %}
@ -104,7 +104,7 @@ new Style(x => x.OfType<StackPanel>().Child().OfType<Button>());
A child selector is defined by separating two selectors with a `>` character. This selector matches _direct children in the logical tree_, so in the example above the selector will match any `Button` that is a direct logical child of a `StackPanel`.
### Descendant <a id="descendant"></a>
## Descendant <a id="descendant"></a>
{% tabs %}
{% tab title="XAML" %}
@ -122,7 +122,7 @@ new Style(x => x.OfType<StackPanel>().Descendant().OfType<Button>());
When two selectors are separated by a space, then the selector will match descendants in the logical tree, so in this case the selector will match any `Button` that is a logical descendant of a `StackPanel`.
### PropertyEquals <a id="propertyequals"></a>
## PropertyEquals <a id="propertyequals"></a>
{% tabs %}
{% tab title="XAML" %}
@ -140,7 +140,7 @@ new Style(x => x.OfType<Button>().PropertyEquals(Button.IsDefaultProperty, true)
Matches any control which has the specified property set to the specified value.
### Template <a id="template"></a>
## Template <a id="template"></a>
{% tabs %}
{% tab title="XAML" %}
@ -158,7 +158,7 @@ new Style(x => x.OfType<Button>().Template().OfType<ContentPresenter>());
Matches a control in a control template. All other selectors listed here work on the logical tree. If you wish to select a control in a control template then you must use this selector. The example selects `ContentPresenter` controls in the templates of `Button`s.
### Not <a id="not"></a>
## Not <a id="not"></a>
{% tabs %}
{% tab title="XAML" %}

2
docs/templates/data-templates.md поставляемый
Просмотреть файл

@ -79,7 +79,7 @@ The easiest way to do this on `Window` \(and any control that inherits from `Con
</Window>
```
![Student first and last name](../../.gitbook/assets/student-first-last-name%20%281%29%20%281%29.png)
![Student first and last name](../../.gitbook/assets/student-first-last-name%20%281%29%20%281%29%20%281%29.png)
The data template for the window content doesn't only come from the `ContentTemplate` property. Every control also has a `DataTemplates` collection into which any number of data templates can be placed. If a control doesn't have a template set locally \(e.g. in `ContentTemplate`\) then it will look in its `DataTemplates` collection for a matching template. If a match isn't found there it will then go on to search its parent's `DataTemplates`, then its grandparent's, and so on until it reaches the `Window`. If it _still_ hasn't found a match it will then look in `App.xaml`/`App.axaml` for a matching `DataTemplate` and finally when all those options have been exhausted it will simply call `.ToString()` on the object.

Просмотреть файл

@ -4,7 +4,7 @@ Avalonia uses XAML to define user-interfaces. XAML is an XML-based markup langua
This section is intended as a basic introduction to using XAML in Avalonia. For more information see the [Microsoft XAML documentation for WPF](https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-overview-wpf) or [Microsoft XAML documentation for UWP](https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/xaml-overview) - many of the concepts are the same between frameworks.
### XAML or AXAML file? <a id="xaml-or-axaml-file"></a>
## XAML or AXAML file? <a id="xaml-or-axaml-file"></a>
The traditional extension for XAML files is `.xaml` but due to problems with Visual Studio we have been forced to move to our own `.axaml` extension for Avalonia XAML files. From version 0.9.11 Avalonia XAML files created in Visual Studio use the `.axaml` extension and from version 0.10 all of our templates will be standardized on using the `.axaml` extension.
@ -12,7 +12,7 @@ For more information see [https://github.com/AvaloniaUI/Avalonia/issues/4102](ht
Both `.xaml` and `.axaml` will be supported going foward, so feel free to use the extension you prefer.
### Format of an Avalonia XAML File <a id="format-of-an-avalonia-xaml-file"></a>
## Format of an Avalonia XAML File <a id="format-of-an-avalonia-xaml-file"></a>
A basic Avalonia XAML file looks like this:
@ -30,7 +30,7 @@ There are three parts to this file:
* `xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"` - this is the XAML-language XAML namespace. This isn't strictly necessary, but you will probably need it for accessing certain features of the XAML language.
* `x:Class="AvaloniaApplication1.MainWindow"` - this tells the XAML compiler where to find the associated class for this file, defined in [code-behind](https://docs.avaloniaui.net/guides/basics/code-behind)
### Declaring Controls <a id="declaring-controls"></a>
## Declaring Controls <a id="declaring-controls"></a>
Controls are added to the XAML by adding an XML element with the control's class name. For example to add a button as the child of the window you would write:
@ -43,7 +43,7 @@ Controls are added to the XAML by adding an XML element with the control's class
See the [controls documentation](https://docs.avaloniaui.net/docs/controls) for a list of the controls included with Avalonia.
### Setting Properties <a id="setting-properties"></a>
## Setting Properties <a id="setting-properties"></a>
You can set a property of a control by adding an XML attribute to an element. For example to create a button with a blue background you could write:
@ -56,7 +56,7 @@ You can set a property of a control by adding an XML attribute to an element. Fo
You can also use _property element syntax_ for setting properties. For more information see the [WPF documentation](https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-overview-wpf#property-element-syntax).
### Content Properties <a id="content-properties"></a>
## Content Properties <a id="content-properties"></a>
You may notice that the button above has its "Hello World!" content placed directly inside the XML element. This could also be written as a property using:
@ -69,7 +69,7 @@ You may notice that the button above has its "Hello World!" content placed direc
This is because [`Button.Content`](http://avaloniaui.net/api/Avalonia.Controls/ContentControl/4B02A756) is declared as a _`[Content]` Property_ which means that any content placed inside its XML tag will be assigned to this property.
### Binding <a id="binding"></a>
## Binding <a id="binding"></a>
You can bind a property using the `{Binding}` markup extension:
@ -82,7 +82,7 @@ You can bind a property using the `{Binding}` markup extension:
For more information, see the [binding documentation](http://avaloniaui.net/docs/binding).
### Code-behind <a id="code-behind"></a>
## Code-behind <a id="code-behind"></a>
Many XAML files also have an associated _code-behind_ file which usually has the extension `.xaml.cs`. For more information see the [codebehind documentation](http://avaloniaui.net/docs/quickstart/codebehind).

Просмотреть файл

@ -1,6 +1,6 @@
# Add Content to Dialog
### Adding Content to the Dialog <a id="adding-content-to-the-dialog"></a>
## Adding Content to the Dialog <a id="adding-content-to-the-dialog"></a>
Inside the dialog we would like the user to search for albums, and then select an album to buy.
@ -29,7 +29,7 @@ Declare a `<DockPanel>`.
```markup
<DockPanel>
</DockPanel>
```
@ -38,7 +38,7 @@ Inside the `DockPanel` add a `<StackPanel>`. Set `DockPanel.Dock="Top"` on the `
```markup
<DockPanel>
<StackPanel DockPanel.Dock="Top">
</StackPanel>
</DockPanel>
```
@ -68,7 +68,7 @@ namespace Avalonia.MusicStore.ViewModels
public class MusicStoreViewModel : ViewModelBase
{
private string? _searchText;
public string? SearchText
{
get => _searchText;
@ -95,13 +95,13 @@ namespace Avalonia.MusicStore.ViewModels
{
private bool _isBusy;
private string? _searchText;
public string? SearchText
{
get => _searchText;
set => this.RaiseAndSetIfChanged(ref _searchText, value);
}
public bool IsBusy
{
get => _isBusy;
@ -168,12 +168,12 @@ Return to the `MusicStoreViewModel.cs` file and add the following code.
private AlbumViewModel? _selectedAlbum;
public ObservableCollection<AlbumViewModel> SearchResults { get; } = new();
public AlbumViewModel? SelectedAlbum
{
get => _selectedAlbum;
set => this.RaiseAndSetIfChanged(ref _selectedAlbum, value);
}
}
```
As you can see the `SelectedAlbum` property is implemented with the by now familiar pattern.
@ -248,13 +248,12 @@ You `MusicStoreWindow.axaml` should look like this.
MaterialOpacity="0.65" />
</ExperimentalAcrylicBorder.Material>
</ExperimentalAcrylicBorder>
<Panel Margin="40">
<local:MusicStoreView />
</Panel>
</Panel>
</Window>
```
Run the application:

Просмотреть файл

@ -1,6 +1,6 @@
# Add Items to Users Collection
### Adding Albums to the Users Collection <a id="adding-albums-to-the-users-collection"></a>
## Adding Albums to the Users Collection <a id="adding-albums-to-the-users-collection"></a>
Ok so now the user can find albums to purchase, it would be nice if the user could see which albums are in their collection. To do this we can add a similar UI to the MainWindow.
@ -39,21 +39,21 @@ We can then use an `ItemsControl` instead of a `ListBox` as we did before. An `I
MaterialOpacity="0.65" />
</ExperimentalAcrylicBorder.Material>
</ExperimentalAcrylicBorder>
<Panel Margin="40">
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Command="{Binding BuyMusicCommand}">
<PathIcon Data="{StaticResource store_microsoft_regular}" />
</Button>
<TextBlock IsVisible="{Binding CollectionEmpty}" Text="Its lonely in here. Purchase some music to get your collection started." HorizontalAlignment="Center" VerticalAlignment="Center" />
<ItemsControl Margin="0 40 0 0" Items="{Binding Albums}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:AlbumView Margin="0 0 20 20" />
@ -75,7 +75,7 @@ public bool CollectionEmpty
get => _collectionEmpty;
set => this.RaiseAndSetIfChanged(ref _collectionEmpty, value);
}
public ObservableCollection<AlbumViewModel> Albums { get; } = new();
```

Просмотреть файл

@ -1,6 +1,6 @@
# Displaying Images
### Displaying Album Cover Images <a id="displaying-album-cover-images"></a>
## Displaying Album Cover Images <a id="displaying-album-cover-images"></a>
So we have the Albums showing with the Artist name and Title, however if we can download the Album art and display it, this will really bring the app alive.
@ -64,7 +64,7 @@ namespace Avalonia.MusicStore.ViewModels
get => _cover;
private set => this.RaiseAndSetIfChanged(ref _cover, value);
}
public async Task LoadCover()
{
await using (var imageStream = await _album.LoadCoverBitmapAsync())
@ -122,8 +122,8 @@ private async void DoSearch(string s)
{
IsBusy = true;
SearchResults.Clear();
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
var albums = await Album.SearchAsync(s);
@ -134,7 +134,7 @@ private async void DoSearch(string s)
SearchResults.Add(vm);
}
if (!_cancellationTokenSource.IsCancellationRequested)
{
LoadCovers(_cancellationTokenSource.Token);