ToggleButtonAutomationPeer Toggle()不执行命令

时间:2014-07-15 15:43:37

标签: c# .net wpf ui-automation

我正在尝试自动化ToggleButton。为此我正在使用ToggleButtonAutomationPeer,如清单中所示。 问题是,当使用AutomationPeer的Toggle()方法时,不执行按钮的命令。

XAML中的ToggleButton

<ToggleButton Name="mToggle" Command="{Binding SomeCommand}"></ToggleButton>

用于自动化ToggleButton

的代码
var peer = new ToggleButtonAutomationPeer(mToggle);
var toggleProvider = peer.GetPattern(PatternInterface.Toggle) as IToggleProvider;
if (toggleProvider != null) toggleProvider.Toggle();

我发现执行ToggleButton命令的唯一方法是使用这行代码

mToggle.Command.Execute(null);

有人可能知道原因或更好的方法吗?

提前致谢

修改

基于Vladimir Perevalov的答案,我派生了ToggleButtonAutomationPeer类,并实施了IInvokeProvider。 由于OnClick()方法似乎受到保护,因此我使用Reflection来获取方法并调用它。 我对使用Reflection感觉不太舒服......我在这里错过了一个更好的方法吗?

class MyToggleButtonAutomationPeer : ToggleButtonAutomationPeer, IInvokeProvider
{
    public MyToggleButtonAutomationPeer(ToggleButton owner) 
        : base(owner)
    {}

    public override object GetPattern(PatternInterface patternInterface)
    {
        return patternInterface == PatternInterface.Invoke ? this : base.GetPattern(patternInterface);
    }

    public void Invoke()
    {
        var dynMethod = Owner.GetType().GetMethod("OnClick", BindingFlags.NonPublic | BindingFlags.Instance);
        dynMethod.Invoke(Owner, null);
    }
}

到目前为止,非常感谢:)

1 个答案:

答案 0 :(得分:0)

这似乎是实施中的一个错误。我查看了ToggleButton及其基础 - ButtonBase的来源。看起来当你调用自动化同级时,它与调用ToggleButton.IsChecked相同(这也不会调用命令)。只有在单击ToggleButton时才会调用该命令。因为它会

  1. 更改IsChecked属性
  2. 打电话给基地。点击。哪个是ButtonBase.OnClick,它将调用该命令。
  3. 我尝试使用

    peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider
    

    但这也行不通,因为IInvokeProvider是由ButtonAutomationPeer实现的,而不是ButtonBaseAutomationPeer,它是ToggleButtonAutomationPeer的基础。

    所以在我看来,你应该为ToggleButton实现自己的自动化对等体,它在Toggle方法中应该调用OnClick而不是OnToggle,一切都应该工作。或者您可以继承ToggleButtonAutomationPeer并另外实现IInvokeProvider并在其Invoke方法中调用OnClick。