2014-07-15 55 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 –