Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public partial class MainWindowViewModel : ViewModelBase

public IObservable<int> Values { get; }

public ICommand InitializeCommand { get; set; }

public ICommand MoveLeftCommand { get; set; }

public ICommand MoveRightCommand { get; set; }
Expand All @@ -31,6 +33,8 @@ public MainWindowViewModel()
{
Count = 0;
Position = 100.0;
InitializeCommand = ReactiveCommand.Create(Initialize);
MoveLeftCommand = ReactiveCommand.Create(() => Position -= 5.0);
MoveLeftCommand = ReactiveCommand.Create(() => Position -= 5.0);
MoveRightCommand = ReactiveCommand.Create(() => Position += 5.0);
ResetMoveCommand = ReactiveCommand.Create(() => Position = 100.0);
Expand Down Expand Up @@ -89,6 +93,11 @@ public MainWindowViewModel()
Values = Observable.Interval(TimeSpan.FromSeconds(1)).Select(_ => _value++);
}

private void Initialize()
{
Console.WriteLine("InitializeCommand");
}

public void IncrementCount() => Count++;

public void DecrementCount(object? sender, object parameter) => Count--;
Expand Down
10 changes: 9 additions & 1 deletion samples/BehaviorsTestApplication/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<Window x:Class="BehaviorsTestApplication.Views.MainWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:BehaviorsTestApplication.ViewModels"
xmlns:views="using:BehaviorsTestApplication.Views"
Title="XamlBehaviors Test Application" Width="1000" Height="700">
Title="XamlBehaviors Test Application" Width="1000" Height="700"
x:DataType="vm:MainWindowViewModel"
x:CompileBindings="False">
<Interaction.Behaviors>
<EventTriggerBehavior EventName="Opened">
<InvokeCommandAction Command="{Binding InitializeCommand, Mode=OneTime}" />
</EventTriggerBehavior>
</Interaction.Behaviors>
<views:MainView />
</Window>
31 changes: 26 additions & 5 deletions src/Avalonia.Xaml.Interactivity/StyledElementBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public void Attach(AvaloniaObject? associatedObject)
Debug.Assert(associatedObject is not null, "Cannot attach the behavior to a null object.");
AssociatedObject = associatedObject ?? throw new ArgumentNullException(nameof(associatedObject));
_dataContextDisposable = SynchronizeDataContext(associatedObject);

// NOTE: Special case handling for TopLevel as it does not trigger attached to logical or visual tree events.
if (AssociatedObject is TopLevel)
{
AttachBehaviorToLogicalTree();
}

OnAttached();
}
Expand Down Expand Up @@ -189,17 +195,32 @@ protected virtual void OnUnloaded()

internal virtual void AttachBehaviorToLogicalTree()
{
if (AssociatedObject is not StyledElement styledElement || styledElement.Parent is null)
StyledElement? parent = null;
AvaloniaObject? templatedParent = null;

if (AssociatedObject is TopLevel topLevel)
{
return;
parent = topLevel;
templatedParent = topLevel.TemplatedParent;
}

if (parent is null)
{
if (AssociatedObject is not StyledElement styledElement || styledElement.Parent is null)
{
return;
}

parent = styledElement;
templatedParent = styledElement.TemplatedParent;
}

// Required for $parent binding in XAML
((ISetLogicalParent)this).SetParent(null);
((ISetLogicalParent)this).SetParent(styledElement);
((ISetLogicalParent)this).SetParent(parent);

// Required for TemplateBinding in XAML
if (styledElement.TemplatedParent is { } templatedParent)
if (templatedParent is not null)
{
TemplatedParentHelper.SetTemplatedParent(this, templatedParent);
}
Expand All @@ -209,7 +230,7 @@ internal virtual void DetachBehaviorFromLogicalTree()
{
((ISetLogicalParent)this).SetParent(null);

if (AssociatedObject is StyledElement { TemplatedParent: not null })
if (AssociatedObject is StyledElement { TemplatedParent: not null } or TopLevel)
{
TemplatedParentHelper.SetTemplatedParent(this, null);
}
Expand Down
16 changes: 13 additions & 3 deletions src/Avalonia.Xaml.Interactivity/StyledElementTrigger.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Avalonia.Controls;
using Avalonia.Metadata;

namespace Avalonia.Xaml.Interactivity;
Expand Down Expand Up @@ -25,12 +26,21 @@ internal override void AttachBehaviorToLogicalTree()
{
base.AttachBehaviorToLogicalTree();

if (AssociatedObject is not StyledElement styledElement || styledElement.Parent is null)
StyledElement? parent = null;

if (AssociatedObject is TopLevel topLevel)
{
return;
parent = topLevel;
}
else
{
if (AssociatedObject is not StyledElement styledElement || styledElement.Parent is null)
{
return;
}

var parent = this;
parent = this;
}

foreach (var action in Actions)
{
Expand Down
Loading