-
-
Notifications
You must be signed in to change notification settings - Fork 19
Add ObservableTriggerBehavior sample page #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
077ad63
fe1348c
6d95fee
df738a0
f3e5220
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <UserControl x:Class="BehaviorsTestApplication.Views.Pages.ObservableTriggerBehaviorView" | ||
| xmlns="https://github.com/avaloniaui" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
| xmlns:vm="using:BehaviorsTestApplication.ViewModels" | ||
| x:DataType="vm:MainWindowViewModel" | ||
| mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="450"> | ||
| <Design.DataContext> | ||
| <vm:MainWindowViewModel /> | ||
| </Design.DataContext> | ||
| <Grid> | ||
| <TextBlock Name="Text" | ||
| FontSize="20" | ||
| HorizontalAlignment="Center" | ||
| VerticalAlignment="Center"> | ||
| <Interaction.Behaviors> | ||
| <ObservableTriggerBehavior x:Name="Observer" | ||
| x:TypeArguments="x:Int32" | ||
| Observable="{Binding Values}"> | ||
| <ChangePropertyAction TargetObject="Text" | ||
| PropertyName="Text" | ||
| Value="{Binding #Observer.Value, StringFormat={} Value: {0}}" /> | ||
| </ObservableTriggerBehavior> | ||
| </Interaction.Behaviors> | ||
| </TextBlock> | ||
| </Grid> | ||
| </UserControl> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| using Avalonia.Controls; | ||
| using Avalonia.Markup.Xaml; | ||
|
|
||
| namespace BehaviorsTestApplication.Views.Pages; | ||
|
|
||
| public partial class ObservableTriggerBehaviorView : UserControl | ||
| { | ||
| public ObservableTriggerBehaviorView() | ||
| { | ||
| InitializeComponent(); | ||
| } | ||
|
|
||
| private void InitializeComponent() | ||
| { | ||
| AvaloniaXamlLoader.Load(this); | ||
| } | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| using System; | ||
| using Avalonia.Reactive; | ||
| using Avalonia.Threading; | ||
| using Avalonia.Xaml.Interactivity; | ||
|
|
||
| namespace Avalonia.Xaml.Interactions.Custom; | ||
|
|
||
| /// <summary> | ||
| /// A trigger that subscribes to an <see cref="IObservable{T}"/> and executes its actions whenever a new value is produced. | ||
| /// The emitted value is exposed through the <see cref="Value"/> property and passed to the actions as a parameter. | ||
| /// </summary> | ||
| /// <typeparam name="T">The type of the observable sequence.</typeparam> | ||
| public class ObservableTriggerBehavior<T> : StyledElementTrigger | ||
| { | ||
| /// <summary> | ||
| /// Identifies the <seealso cref="Observable"/> avalonia property. | ||
| /// </summary> | ||
| public static readonly StyledProperty<IObservable<T>?> ObservableProperty = | ||
| AvaloniaProperty.Register<ObservableTriggerBehavior<T>, IObservable<T>?>(nameof(Observable)); | ||
|
Check warning on line 19 in src/Avalonia.Xaml.Interactions.Custom/Core/ObservableTriggerBehavior.cs
|
||
|
|
||
| /// <summary> | ||
| /// Identifies the <seealso cref="Value"/> avalonia property. | ||
| /// </summary> | ||
| public static readonly StyledProperty<T?> ValueProperty = | ||
| AvaloniaProperty.Register<ObservableTriggerBehavior<T>, T?>(nameof(Value)); | ||
|
Check warning on line 25 in src/Avalonia.Xaml.Interactions.Custom/Core/ObservableTriggerBehavior.cs
|
||
|
|
||
| private IDisposable? _subscription; | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the observable sequence that triggers the actions. This is an avalonia property. | ||
| /// </summary> | ||
| public IObservable<T>? Observable | ||
| { | ||
| get => GetValue(ObservableProperty); | ||
| set => SetValue(ObservableProperty, value); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the last value received from the <see cref="Observable"/>. This is an avalonia property. | ||
| /// </summary> | ||
| public T? Value | ||
| { | ||
| get => GetValue(ValueProperty); | ||
| private set => SetCurrentValue(ValueProperty, value); | ||
| } | ||
|
|
||
| /// <inheritdoc /> | ||
| protected override void OnAttached() | ||
| { | ||
| base.OnAttached(); | ||
| Subscribe(); | ||
| } | ||
|
|
||
| /// <inheritdoc /> | ||
| protected override void OnDetaching() | ||
| { | ||
| base.OnDetaching(); | ||
| _subscription?.Dispose(); | ||
| _subscription = null; | ||
| } | ||
|
|
||
| /// <inheritdoc /> | ||
| protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) | ||
| { | ||
| base.OnPropertyChanged(change); | ||
|
|
||
| if (change.Property == ObservableProperty) | ||
| { | ||
| Subscribe(); | ||
| } | ||
| } | ||
|
|
||
| private void Subscribe() | ||
| { | ||
| _subscription?.Dispose(); | ||
| var observable = Observable; | ||
| if (observable is not null) | ||
| { | ||
| _subscription = observable | ||
| .Subscribe(new AnonymousObserver<T>(value => | ||
| { | ||
| Dispatcher.UIThread.Invoke(() => | ||
| { | ||
| Value = value; | ||
| Execute(value); | ||
| }); | ||
| })); | ||
| } | ||
| } | ||
|
|
||
| private void Execute(object? parameter) | ||
| { | ||
| if (AssociatedObject is null || !IsEnabled) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| Interaction.ExecuteActions(AssociatedObject, Actions, parameter); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.