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
13 changes: 13 additions & 0 deletions src/Controls/src/Core/Setter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ internal void Apply(BindableObject target, SetterSpecificity specificity)
targetObject.SetDynamicResource(Property, dynamicResource.Key, specificity);
else if (Value is IList<VisualStateGroup> visualStateGroupCollection)
targetObject.SetValue(Property, visualStateGroupCollection.Clone(), specificity);
else if (Value is Style style && (Property == StyleableElement.StyleProperty || Property == Span.StyleProperty))
{
// When setting a Style through a Setter (e.g., in VisualStateManager),
// we need to call the Style's Apply method to ensure all its setters are applied
((IStyle)style).Apply(targetObject, specificity);
}
else
targetObject.SetValue(Property, Value, specificity: specificity);
}
Comment thread
Shalini-Ashokan marked this conversation as resolved.
Comment thread
Shalini-Ashokan marked this conversation as resolved.
Comment thread
Shalini-Ashokan marked this conversation as resolved.
Expand All @@ -98,6 +104,13 @@ internal void UnApply(BindableObject target, SetterSpecificity specificity)
targetObject.RemoveBinding(Property, specificity);
else if (Value is DynamicResource dynamicResource)
targetObject.RemoveDynamicResource(Property, specificity);
else if (Value is Style style && (Property == StyleableElement.StyleProperty || Property == Span.StyleProperty))
{
// When un-applying a Style that was set through a Setter,
// we need to call the Style's UnApply method to properly clean up
((IStyle)style).UnApply(targetObject);
return;
}
targetObject.ClearValue(Property, specificity);
Comment thread
Shalini-Ashokan marked this conversation as resolved.
}
Comment thread
Shalini-Ashokan marked this conversation as resolved.
}
Expand Down
91 changes: 91 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue17175.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue17175"
Title="Issue 17175 - VSM Can Set Style Property">

<ContentPage.Resources>
<ResourceDictionary>
<!-- Base style without VSM -->
<Style x:Key="BaseButtonStyle"
TargetType="Button">
<Setter Property="BackgroundColor"
Value="LightBlue"/>
<Setter Property="TextColor"
Value="Black"/>
<Setter Property="Padding"
Value="20"/>
</Style>

<!-- Highlighted style for Selected state -->
<Style x:Key="HighlightButtonStyle"
TargetType="Button">
<Setter Property="BackgroundColor"
Value="Orange"/>
<Setter Property="TextColor"
Value="White"/>
<Setter Property="Padding"
Value="20"/>
<Setter Property="FontAttributes"
Value="Bold"/>
</Style>

<!-- Disabled style -->
<Style x:Key="DisabledButtonStyle"
TargetType="Button">
<Setter Property="BackgroundColor"
Value="Gray"/>
<Setter Property="TextColor"
Value="DarkGray"/>
<Setter Property="Padding"
Value="20"/>
<Setter Property="Text"
Value="State: Disabled"/>
</Style>
</ResourceDictionary>
</ContentPage.Resources>

<VerticalStackLayout Padding="20"
Spacing="10">
<Button x:Name="TestButton"
Text="State: Normal"
Style="{StaticResource BaseButtonStyle}"
HorizontalOptions="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource BaseButtonStyle}"/>
<Setter Property="Text"
Value="State: Normal"/>
</VisualState.Setters>
</VisualState>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource HighlightButtonStyle}"/>
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="Style"
Value="{StaticResource DisabledButtonStyle}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>

<Label x:Name="StateLabel"
AutomationId="StateLabel"
Text="State: Normal"
HorizontalOptions="Center"
Margin="0,10,0,0"/>

<Button Text="Go to Disabled"
AutomationId="GoToDisabledButton"
Clicked="OnGoToDisabledClicked"
HorizontalOptions="Center"/>
</VerticalStackLayout>
</ContentPage>
16 changes: 16 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue17175.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 17175, "VisualStateManager should be able to set Style property dynamically", PlatformAffected.All)]
public partial class Issue17175 : ContentPage
{
public Issue17175()
{
InitializeComponent();
}

private void OnGoToDisabledClicked(object sender, System.EventArgs e)
{
TestButton.IsEnabled = !TestButton.IsEnabled;
StateLabel.Text = TestButton.Text;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue17175 : _IssuesUITest
{
public override string Issue => "VisualStateManager should be able to set Style property dynamically";

public Issue17175(TestDevice device) : base(device) { }

[Test]
[Category(UITestCategories.Button)]
public void VisualStateManagerCanSetStyleProperty()
{
App.WaitForElement("GoToDisabledButton");

// Normal → Disabled
App.Tap("GoToDisabledButton");
var stateLabel = App.FindElement("StateLabel").GetText();
Assert.That(stateLabel, Is.EqualTo("State: Disabled"));

// Disabled → Normal (verifies UnApply restores correctly)
App.Tap("GoToDisabledButton");
stateLabel = App.FindElement("StateLabel").GetText();
Assert.That(stateLabel, Is.EqualTo("State: Normal"));

// Normal → Disabled again (verifies second cycle works)
App.Tap("GoToDisabledButton");
stateLabel = App.FindElement("StateLabel").GetText();
Assert.That(stateLabel, Is.EqualTo("State: Disabled"));
}
}
Loading