Skip to content

Commit

Permalink
fix: Fix support of the CustomVisualStateMamager
Browse files Browse the repository at this point in the history
  • Loading branch information
dr1rrb committed Nov 22, 2021
1 parent 2d35d99 commit 4cb5983
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,20 @@ public void When_TransitionAndSetter_InCompatibilityMode_Then_SetterAppliedBefor
}
}

[TestMethod]
public void When_CustomManager_Then_UseIt()
{
var (control, group) = Setup();
var vsm = new CustomManager();
VisualStateManager.SetCustomVisualStateManager((FrameworkElement)control.TemplatedRoot, vsm);

VisualStateManager.GoToState(control, "state1", true);
VisualStateManager.GoToState(control, "state2", true);

Assert.IsTrue(new[] { "state1", "state2" }.SequenceEqual(vsm.States));
}


private static (Control control, VisualStateGroup states) Setup()
{
var control = new Control { Name = "control", Tag = "initial", Template = new ControlTemplate(() => new Grid()) };
Expand All @@ -247,7 +261,7 @@ private static (Control control, VisualStateGroup states) Setup()
}

private static VisualState State(int id)
=> new VisualState
=> new()
{
Name = "state" + id,
Setters = {new Setter(new TargetPropertyPath("control", "Tag"), "state" + id)}
Expand Down Expand Up @@ -305,5 +319,17 @@ internal void Unset()
IsActive = false;
}
}

private class CustomManager : VisualStateManager
{
public List<string> States { get; } = new();

/// <inheritdoc />
protected override bool GoToStateCore(Control control, FrameworkElement templateRoot, string stateName, VisualStateGroup @group, VisualState state, bool useTransitions)
{
States.Add(stateName);
return base.GoToStateCore(control, templateRoot, stateName, @group, state, useTransitions);
}
}
}
}
28 changes: 12 additions & 16 deletions src/Uno.UI/UI/Xaml/VisualStateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,26 +160,22 @@ public static bool GoToState(Control control, string stateName, bool useTransiti
return false;
}

var vsm = GetCustomVisualStateManager(control) ?? GetVisualStateManager(control);
if (vsm is null)
{
if (_log.IsEnabled(Uno.Foundation.Logging.LogLevel.Debug))
{
_log.DebugFormat("Failed to set state [{0}], there is no VisualStateManager on [{1}]", stateName, control);
}
#if __WASM__
TryAssignDOMVisualStates(groups, templateRoot);
#endif

return false;
if (templateRoot is not FrameworkElement fwRoot)
{
// For backward compatibility!
return GetVisualStateManager(control).GoToStateCorePrivateBaseImplementation(control, group, state, useTransitions);
}

// Note: We resolve the 'CustomVisualStateManager' on the 'fwRoot' like UWP,
// but for compatibility reason we resolve the default visual state manager on the 'control' itself.
// We should validate the behavior on UWP, including for controls that does not have templates!
var vsm = GetCustomVisualStateManager(fwRoot) ?? GetVisualStateManager(control);

var output = templateRoot is FrameworkElement fwRoot
? vsm.GoToStateCore(control, fwRoot, stateName, group, state, useTransitions)
: vsm.GoToStateCorePrivateBaseImplementation(control, group, state, useTransitions); // For backward compatibility!

#if __WASM__
TryAssignDOMVisualStates(groups, templateRoot);
#endif
return output;
return vsm.GoToStateCore(control, fwRoot, stateName, group, state, useTransitions);
}

protected virtual bool GoToStateCore(Control control, FrameworkElement templateRoot, string stateName, VisualStateGroup group, VisualState state, bool useTransitions)
Expand Down

0 comments on commit 4cb5983

Please sign in to comment.