2015-02-06 31 views
-1

有幾個在線的例子如何禁用菜單項的孩子(例如,使用DropDownOpening事件),但我想創建一個繼承類ToolStripMenuItem並能決定它自己是否應該啓用。如何在顯示時禁用或(取消)檢查ToolStripMenuItem?

事情是這樣的:

Public Class SmartMenuItem 
    Inherits ToolStripMenuItem 

    Public Sub New(text As String) 
     MyBase.New(text) 
     AddHandler MyBase.VisibleChanged, AddressOf enableSelf 
    End Sub 

    Private Sub enableSelf(sender As Object, e As System.EventArgs) 
     Me.Enabled = MagicFunctionBooleanResult() 
    End Sub 

End Class 

VisibleChanged因爲我希望的那樣也可以找到任何其他事件事件不起作用。

我也試過DropDownOpening事件對於項目本身,但只被用相當多的延遲,所以解僱,如果用戶足夠快,他們仍然可以,一旦它被顯示單擊該項目。

這似乎是一個如此明顯的特徵,我害怕我失去了一些東西...顯而易見。

任何想法?

編輯:更改經過屬性是相同的交易,當然...

+0

這是DropDownOpening。主知道你做了什麼來讓它「緩慢」。 MessageBox不是調試器。 – 2015-02-06 00:22:34

+0

這種延遲是通過設計來防止子項目在您通過將鼠標拖動(懸停)在多個用戶所做的每個項目上瀏覽菜單時惱人地彈出。 – mike 2015-02-06 09:19:26

+0

我不知道爲什麼這個問題被低估了......任何提示我做錯了什麼或有關如何防止反對票的建議都會很好。 – mike 2015-02-06 09:42:53

回答

0

我着急,但累。一覺醒來,我找到了解決辦法,這的確出現了明顯的一次,我翻譯的短語「顯示」我的問題「油漆」:

Public Class SmartMenuItem 
    Inherits ToolStripMenuItem 

    Public Sub New(text As String) 
     MyBase.New(text) 
    End Sub 

    Protected Overrides Sub OnPaint(e As PaintEventArgs) 
     Me.Enabled = MagicEnabledFunction() 
     Me.Checked = MagicCheckedFunction() 
     Me.Text = MagicTextFunction() 

     MyBase.OnPaint(e) 
    End Sub 

End Class 

通過重寫事件處理函數(而不是使用的AddHandler我。 Paint)您可以確定自定義代碼在基類處理繪製事件之前執行,這是更改顯示相關屬性的最佳機會,例如啓用,檢查,文本。

更新:利用上述技術,在我的項目後,我結束了一個基類,消除在初始解一個很大的缺點:快捷鍵仍然會觸發項的點擊事件,即使它被禁用。

首先,基類:

Public Class MenuItem 
    Inherits ToolStripMenuItem 

    Public Delegate Sub ClickDelegate() 

    Public Sub New(text As String, shortcut As Windows.Forms.Keys, clickCallback As ClickDelegate) 
     MyBase.New(text) 

     AddHandler Me.Click, Sub(sender As Object, e As System.EventArgs) 
           If Me.enabledCallback Then 
            'NOTE: shortcut keys trigger the event even, if the item is not enabled; so check here to prevent their execution 
            clickCallback.Invoke() 
           End If 
          End Sub 


     If shortcut <> Keys.None Then 
      Me.ShortcutKeys = shortcut 
      Me.ShowShortcutKeys = True 
     End If 
    End Sub 

    Protected Overrides Sub OnPaint(e As PaintEventArgs) 
     'Store the current Enabled state before painting 
     Dim _enabled As Boolean = Me.Enabled 

     'Set Enabled/Checked according to the callbacks 
     Me.Enabled = enabledCallback() 
     Me.Checked = checkedCallback() 

     'Paint the item 
     MyBase.OnPaint(e) 

     'Restore Enabled 
     Me.Enabled = _enabled 


     'NOTES: 
     '- If the native Enabled-property is not disabled, then the mechanism above allows the item to always respond to shortcut keys. 
     '- In the lamda click handler (which is also called when a shortcut is used) the enabledCallback will be checked to verify 
     ' that the clickCallback should really be executed. 
     '- This way, if the criteria for enabling/disabling the item (coded in enabledCallback) change, the shortcut keys will work as expected. 
     '- Otherwise the enabled state would only be refreshed on paint and, if enabledCallback() = false, then the shortcut keys could not 
     ' be used (until the item is painted again). 
     '- Query Me.Enabled (or MyBase.enabledCallback) within the enabledCallback override to allow for enabling/disabling regardless of 
     ' the criteria coded in the callback. 
     '- A similar mechanism for Checked is not implemented, assuming the property is only relevant for painting and is not queried anywhere else. 


    End Sub 
    Protected Overridable Function enabledCallback() As Boolean 
     Return Me.Enabled 
    End Function 

    Protected Overridable Function checkedCallback() As Boolean 
     Return Me.Checked 
    End Function 
End Class 

其次,派生類:

Public Class SelectionMenuItem 
    Inherits Wd.Menu.MenuItem 

    Public Sub New(text As String, shortCut As Windows.Forms.Keys, callback As MenuItem.ClickDelegate, minCount As Integer, Optional maxCount As Integer = 1000) 
     MyBase.New(text, shortCut, callback) 

     _minCount = minCount 
     _maxCount = maxCount 
    End Sub 

    Private _minCount As Integer 
    Private _maxCount As Integer 

    Protected Overrides Function enabledCallback() As Boolean 
     Return (Magic.Selection.Count >= _minCount) AndAlso (Magic.Selection.Count <= _maxCount) 
    End Function 
End Class 

我希望包括在上述的幫助代碼中的註釋解釋我是如何傳開了;現在還沒有時間詳細說明; o)

0

我還是設法看到當你使用的自定義ToolStripMenuItem的DropDownOpening事件時,在該項目上你的鼠標,你引用了延遲。當您將鼠標懸停在項目上時,即使它沒有任何子菜單,也是,然後嘗試打開任何子菜單。這是你看到的延遲。

嘗試使用OwnerChanged事件,而不是知道當父項是做DropDownOpening事件,而不是:

Public Class SmartMenuItem 
    Inherits ToolStripMenuItem 

    Public Sub New(text As String) 
    MyBase.New(text) 
    End Sub 

    Private Sub SmartMenuItem_OwnerChanged(sender As Object, e As EventArgs) _ 
             Handles Me.OwnerChanged 
    If Me.OwnerItem IsNot Nothing Then 
     Dim dropMenu As ToolStripMenuItem = TryCast(Me.OwnerItem, ToolStripMenuItem) 
     If dropMenu IsNot Nothing Then 
     AddHandler dropMenu.DropDownOpening, Sub() Me.Enabled = MagicBooleanResult() 
     End If 
    End If 
    End Sub 
End Class 
相關問題