2015-02-06 36 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 
相关问题