Skip to content

Commit da28a6e

Browse files
grokysmaxkatz6
authored andcommitted
Don't share style instances with Or selector. (#13969)
* Added failing test for #13910. * Don't share style instances with Or selector. Fixes #13910.
1 parent 2d54e31 commit da28a6e

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

src/Avalonia.Base/Styling/ControlTheme.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ internal SelectorMatchResult TryAttach(StyledElement target, FrameType type)
4848

4949
if (HasSettersOrAnimations && TargetType.IsAssignableFrom(StyledElement.GetStyleKey(target)))
5050
{
51-
Attach(target, null, type);
51+
Attach(target, null, type, true);
5252
return SelectorMatchResult.AlwaysThisType;
5353
}
5454

src/Avalonia.Base/Styling/Style.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ internal SelectorMatchResult TryAttach(StyledElement target, object? host, Frame
7474

7575
if (match.IsMatch)
7676
{
77-
Attach(target, match.Activator, type);
77+
Attach(target, match.Activator, type, Selector is not OrSelector);
7878
}
7979

8080
result = match.Result;

src/Avalonia.Base/Styling/StyleBase.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,24 @@ public bool TryGetResource(object key, ThemeVariant? themeVariant, out object? r
9292
return false;
9393
}
9494

95-
internal ValueFrame Attach(StyledElement target, IStyleActivator? activator, FrameType type)
95+
internal ValueFrame Attach(
96+
StyledElement target,
97+
IStyleActivator? activator,
98+
FrameType type,
99+
bool canShareInstance)
96100
{
97101
if (target is not AvaloniaObject ao)
98102
throw new InvalidOperationException("Styles can only be applied to AvaloniaObjects.");
99103

100104
StyleInstance instance;
101105

102-
if (_sharedInstance is not null)
106+
if (_sharedInstance is not null && canShareInstance)
103107
{
104108
instance = _sharedInstance;
105109
}
106110
else
107111
{
108-
var canShareInstance = activator is null;
112+
canShareInstance &= activator is null;
109113

110114
instance = new StyleInstance(this, activator, type);
111115

tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,28 @@ public void Animations_With_Activator_Trigger_Should_Be_Activated_And_Deactivate
10291029
Assert.Equal(Brushes.Blue, border.Background);
10301030
}
10311031

1032+
[Fact]
1033+
public void Should_Not_Share_Instance_When_Or_Selector_Is_Present()
1034+
{
1035+
// Issue #13910
1036+
Style style = new Style(x => Selectors.Or(x.OfType<Class1>(), x.OfType<Class2>().Class("bar")))
1037+
{
1038+
Setters =
1039+
{
1040+
new Setter(Class1.FooProperty, "Foo"),
1041+
},
1042+
};
1043+
1044+
var target1 = new Class1 { Classes = { "foo" } };
1045+
var target2 = new Class2();
1046+
1047+
StyleHelpers.TryAttach(style, target1);
1048+
StyleHelpers.TryAttach(style, target2);
1049+
1050+
Assert.Equal("Foo", target1.Foo);
1051+
Assert.Equal("foodefault", target2.Foo);
1052+
}
1053+
10321054
private class Class1 : Control
10331055
{
10341056
public static readonly StyledProperty<string> FooProperty =
@@ -1063,5 +1085,22 @@ protected override Size MeasureOverride(Size availableSize)
10631085
throw new NotImplementedException();
10641086
}
10651087
}
1088+
1089+
private class Class2 : Control
1090+
{
1091+
public static readonly StyledProperty<string> FooProperty =
1092+
Class1.FooProperty.AddOwner<Class2>();
1093+
1094+
public string Foo
1095+
{
1096+
get { return GetValue(FooProperty); }
1097+
set { SetValue(FooProperty, value); }
1098+
}
1099+
1100+
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
1101+
{
1102+
base.OnPropertyChanged(change);
1103+
}
1104+
}
10661105
}
10671106
}

0 commit comments

Comments
 (0)