2014-07-15 54 views
0

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

切换按钮在XAML

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

用于我发现执行该切换按钮的命令的唯一方法是使用这行代码自动切换按钮

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

代码

mToggle.Command.Execute(null); 

有人可能知道这样做的原因或更好的方式吗?提前

编辑

由于基于对Vladimir Perevalov答案我得到的ToggleButtonAutomationPeer类,也实现了IInvokeProvider。 由于OnClick()方法似乎被保护,我使用反射来获取方法并调用它。 我不太喜欢使用反射...我错过了一个更好的方法吗?

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); 
    } 
} 

反正非常感谢迄今:)

回答

0

这似乎是在实现中的错误。我查看了ToggleButton的源代码及其基础 - ButtonBase。它看起来像当你调用自动化peer时,它和调用ToggleButton.IsChecked(这也不会调用该命令)是一样的。只有当你点击ToggleButton时才会调用该命令。因为它会

  1. 更改物业器isChecked
  2. 调用base.OnClick。 ButtonBase.OnClick是哪个,哪个将调用该命令。

我试图用

peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider 

但是,这并不也行,因为IInvokeProvider由ButtonAutomationPeer,不ButtonBaseAutomationPeer这是ToggleButtonAutomationPeer基地实施。

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

+0

到目前为止谢谢你:)我尝试了你的建议并更新了我的问题。你知道比使用反射更好的方法吗? – sebhaub

+0

如果你看看ToggleButtonAutomationPeer的实现,你可以看到它可以直接访问实际上受保护的ToggleButton.OnToggle()方法。我认为这是通过“InternalsVisibleTo”属性完成的。 http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx –