|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using Microsoft.VisualStudio.Threading;
namespace Microsoft.VisualStudio.IntegrationTest.Utilities.Input
{
public static class ButtonBaseExtensions
{
private static readonly MethodInfo s_executeCoreMethod;
static ButtonBaseExtensions()
{
var methodInfo = typeof(RoutedCommand).GetMethod("ExecuteCore", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(object), typeof(IInputElement), typeof(bool) }, null);
s_executeCoreMethod = methodInfo;
//s_executeCore = (Action<RoutedCommand, object, IInputElement, bool>)Delegate.CreateDelegate(typeof(Action<RoutedCommand, object, IInputElement, bool>), firstArgument: null, methodInfo);
}
public static async Task<bool> SimulateClickAsync(this ButtonBase button, JoinableTaskFactory joinableTaskFactory)
{
await joinableTaskFactory.SwitchToMainThreadAsync();
if (!button.IsEnabled || !button.IsVisible)
{
return false;
}
if (button is RadioButton radioButton)
{
ISelectionItemProvider peer = new RadioButtonAutomationPeer(radioButton);
peer.Select();
}
else if (button is Button button2)
{
IInvokeProvider peer = new ButtonAutomationPeer(button2);
peer.Invoke();
}
else
{
button.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
ExecuteCommandSource(button, true);
}
// Wait for changes to propagate
await Task.Yield();
return true;
}
private static void ExecuteCommandSource(ICommandSource commandSource, bool userInitiated)
{
var command = commandSource.Command;
if (command is null)
{
return;
}
var commandParameter = commandSource.CommandParameter;
var commandTarget = commandSource.CommandTarget;
if (command is RoutedCommand routedCommand)
{
commandTarget ??= commandSource as IInputElement;
if (routedCommand.CanExecute(commandParameter, commandTarget))
{
s_executeCoreMethod.Invoke(routedCommand, new[] { commandParameter, commandTarget, userInitiated });
//s_executeCore(routedCommand, commandParameter, commandTarget, userInitiated);
}
}
else if (command.CanExecute(commandParameter))
{
command.Execute(commandParameter);
}
}
}
}
|