Skip to content

Commit

Permalink
Fixing SplitButtonAutomationPeer's Invoke implementation (#6918)
Browse files Browse the repository at this point in the history
SplitButtonAutomationPeer's Invoke implementation currently just directly calls the Click event handler, which misses the fact that we also have the option of assigning a command to execute.  Instead of that, I've made it so we just forward the Invoke implementation to the primary button's automation peer, which will ensure that we do everything a button should do in this case.

I also edited the test case using the SplitButton with a command to use Invoke() to test that case as well.
  • Loading branch information
llongley authored Apr 1, 2022
1 parent e3e7da2 commit 97b333a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
6 changes: 5 additions & 1 deletion dev/SplitButton/InteractionTests/SplitButtonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ public void CommandTest()
ClickPrimaryButtonWithKey(splitButton, "ENTER");
Verify.AreEqual("3", executeCountTextBlock.DocumentText);

Log.Comment("Use invoke pattern to execute command");
splitButton.InvokeAndWait();
Verify.AreEqual("4", executeCountTextBlock.DocumentText);

Log.Comment("Verify that setting CanExecute to false disables the primary button");
canExecuteCheckBox.Uncheck();
Wait.ForIdle();
ClickPrimaryButton(splitButton);
Verify.AreEqual("3", executeCountTextBlock.DocumentText);
Verify.AreEqual("4", executeCountTextBlock.DocumentText);
}
}

Expand Down
20 changes: 20 additions & 0 deletions dev/SplitButton/SplitButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,26 @@ void SplitButton::OnClickSecondary(const winrt::IInspectable& sender, const winr
OpenFlyout();
}

void SplitButton::Invoke()
{
bool invoked = false;

if (winrt::AutomationPeer peer = winrt::FrameworkElementAutomationPeer::FromElement(m_primaryButton.get()))
{
if (winrt::IInvokeProvider invokeProvider = peer.GetPattern(winrt::PatternInterface::Invoke).try_as<winrt::IInvokeProvider>())
{
invokeProvider.Invoke();
invoked = true;
}
}

// If we don't have a primary button that provides an invoke provider, we'll fall back to calling OnClickPrimary manually.
if (!invoked)
{
OnClickPrimary(nullptr, nullptr);
}
}

void SplitButton::OnPointerEvent(const winrt::IInspectable& sender, const winrt::PointerRoutedEventArgs& args)
{
winrt::PointerDeviceType pointerDeviceType = args.Pointer().PointerDeviceType();
Expand Down
5 changes: 4 additions & 1 deletion dev/SplitButton/SplitButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ class SplitButton :
bool IsFlyoutOpen() { return m_isFlyoutOpen; };
void OpenFlyout();
void CloseFlyout();
virtual void OnClickPrimary(const winrt::IInspectable& sender, const winrt::RoutedEventArgs& args);
virtual bool InternalIsChecked() { return false; }

void UpdateVisualStates(bool useTransitions = true);

void OnPropertyChanged(const winrt::DependencyPropertyChangedEventArgs& args);

void Invoke();

protected:
virtual void OnClickPrimary(const winrt::IInspectable& sender, const winrt::RoutedEventArgs& args);

bool m_hasLoaded{ false };

private:
Expand Down
2 changes: 1 addition & 1 deletion dev/SplitButton/SplitButtonAutomationPeer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@ void SplitButtonAutomationPeer::Invoke()
{
if (auto splitButton = GetImpl())
{
splitButton->OnClickPrimary(nullptr, nullptr);
splitButton->Invoke();
}
}

0 comments on commit 97b333a

Please sign in to comment.