MenuStrip中不能专注于负载 [英] MenuStrip can't get focus on load

查看:239
本文介绍了MenuStrip中不能专注于负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我willt RY确切地,我有一个主要形式,我们将在Form1称之为Form1的用户有可能,throught菜单条,推出另一种形式,我们将其称之为窗体2,在窗体2我有另一种的MenuStrip和一个DataGridView。

I willt ry to be exact as possible, I have a main form we will call it "Form1" in the Form1 the user have the possibility, throught a menu strip to launch another form, we will call it "Form2", in the Form2 I have another menustrip and a datagridview.

我的问题,当用户启动窗体2我有左键2次点击前的菜单条获得激活我的意思是

My problem when the user launch the Form2 I have to click with the left button 2 time before the menu strip get "activated" what I mean is

  • 在该窗口2负荷
  • 在我点击菜单条项:菜单
  • 没有发生
  • 在我点击另一个时间菜单条向下滚动

这真的是烦人,我不能确定这一点,因为我不知道是什么原因造成它

it's really anoying and I can't fix this because I have no idea what is causing it

如果你们有什么样的解决方案,或需要更多的信息,请告诉我。

if you guys have any kind of solution or need more information just tell me.

这是窗体2名为Ajout.vb

This is the Form2 named Ajout.vb

Imports System.Data.OleDb
Imports System.Globalization

Public Class Ajout
    Private dSet As DataSet
    Private dAdapter As New OleDbDataAdapter
    Private bJustEdit As Boolean = False

    Sub New(ByRef dSet As DataSet, ByRef dAdapter As OleDbDataAdapter)
        InitializeComponent()
        Me.dSet = dSet
        Me.dAdapter = dAdapter
    End Sub

    Private Sub Ajout_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        With DataGridView1
            .DataSource = dSet
            .DataMember = "Articles_table"
            .Columns("Prix").DefaultCellStyle.Format = "C2"
            Console.WriteLine(.Columns("Prix").ValueType)
            For Each clm As DataGridViewColumn In .Columns
                clm.SortMode = DataGridViewColumnSortMode.NotSortable
            Next
        End With
    End Sub

    Private Sub DataGridView1_DataError(ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
        'Quelle est l'erreur
        If (TypeOf (e.Exception) Is ConstraintException) Then
            'Envoie une message box pour informer l'utilisateur avec une possibiliter
            If (drMessageBoxFuntion(0) = Windows.Forms.DialogResult.Yes) Then
                'Possibiliter choisi on regarde si le sender est bien de datagridview pour eviter un erreur de cast
                If (TypeOf sender Is DataGridView) Then
                    'Nouvelle variable car sa devien inlisible avec beaucoup de cast
                    Dim dgvLocal As DataGridView = CType(sender, DataGridView)
                    Dim sNameValue As String = dgvLocal.Rows(e.RowIndex).Cells("Nom").Value.ToString
                    Dim dgvOriginalCells As DataGridViewCellCollection = dgvLocal.Rows(dgvFindRowsBy_Name(sNameValue).Index).Cells
                    Dim dgvErrorCells As DataGridViewCellCollection = dgvLocal.Rows(e.RowIndex).Cells

                    'Regarde si le prix est pareille si faux propose a l'utilisateur d'updater le prix avec le nouveau
                    'ou de simplement ajouter la quantite
                    If (Not Equals(dgvOriginalCells("Prix").Value.ToString, dgvErrorCells("Prix").Value.ToString)) Then
                        'Prix different propose de mettre a jour
                        If (drMessageBoxFuntion(1) = Windows.Forms.DialogResult.Yes) Then
                            dgvOriginalCells("Prix").Value = dErrorRow()
                            dgvOriginalCells("Quantité").Value += dgvErrorCells("Quantité").Value
                        Else
                            dgvOriginalCells("Quantité").Value += dgvErrorCells("Quantité").Value
                        End If
                    Else
                        dgvOriginalCells("Quantité").Value += dgvErrorCells("Quantité").Value
                    End If
                    'Sender inconnu 
                Else
                    MsgBox("Une erreur inconnu est survenu, aucune operation n'a été effectué, vous n'avez qu'à recommencer")
                End If
            End If

            'Si lettre entré, msg pour informer le reste est gerer par le dataset qui n'accepte que
            'les chiffre, car defini dans la database
        ElseIf (TypeOf (e.Exception) Is FormatException) Then
            MsgBox("Vous ne pouvez pas entrer de lettre dans la collone de prix ou de quantité")
        End If
    End Sub


    'Fonction contenant plusieur message box
    Private Function drMessageBoxFuntion(ByVal index As Integer) As DialogResult
        If (index = 0) Then
            Dim drAction As DialogResult = MessageBox.Show("Vous ne pouvez pas ajouter deux fois le même nom," & _
                                               " voulez vous ajouter la quantité du nouvelle arti" & _
                                               "cle a celui deja présent ?", _
                                               "Erreur, article double.", _
                                               MessageBoxButtons.YesNo, _
                                               MessageBoxIcon.Question)
            Return drAction
        ElseIf (index = 1) Then
            Dim drAction As DialogResult = MessageBox.Show("Le prix de vos deux article, de même genre, diffère." & _
                                                           "Voulez-vous mettre a jour le prix à jour (oui), ou " & _
                                                           "simplement ajouter la quantité a l'item déjà présent (no" & _
                                                           "n).", "Erreur, prix different", _
                                                            MessageBoxButtons.YesNo, _
                                                            MessageBoxIcon.Question)
            Return drAction
        End If
        Return Nothing
    End Function

    'Retourne une datagridviewROW et non l'index car permet d'avoir l'objet
    'et donc de prendre la methode index ou autre methode si le besoin est
    Private Function dgvFindRowsBy_Name(ByVal oNameValue As Object) As DataGridViewRow
        For Each row As DataGridViewRow In DataGridView1.Rows
            If row.Cells.Item("Nom").Value = oNameValue Then
                Return row
            End If
        Next
        Return Nothing
    End Function

    'Message pre programmer dans une array permettant l'affichage de message avec une input
    Private Function dErrorRow() As Single
        Dim dNewValue As Object = InputBox("Nouveau prix, entrez uniquement un nombre s'il vous plait.")

        Do Until IsNumeric(dNewValue)
            dNewValue = InputBox("Nouveau prix, entrez uniquement un nombre s'il vous plait.")
        Loop

        Return CType(dNewValue, Single)
    End Function

    Private Sub DataGridView1_RowValidating(sender As Object, e As DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
        If (TypeOf sender Is DataGridView) Then
            Dim dgvRow As DataGridViewRow = CType(sender, DataGridView).Rows(e.RowIndex)
            If (Not ((IsDBNull(dgvRow.Cells("Nom").Value) Or IsDBNull(dgvRow.Cells("Prix").Value) Or IsDBNull(dgvRow.Cells("Quantité").Value)) = (IsDBNull(dgvRow.Cells("Nom").Value) And IsDBNull(dgvRow.Cells("Prix").Value) And IsDBNull(dgvRow.Cells("Quantité").Value)))) Then
                MsgBox("Veuillez remplir toute les cases.")
                e.Cancel = True
            End If
        End If
    End Sub

    Private Sub DataGridView1_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
        If (TypeOf sender Is DataGridView) Then
            Dim dgvRow As DataGridViewRow = CType(sender, DataGridView).Rows(e.RowIndex)

            If (Not dgvRow.IsNewRow) Then
                If (e.ColumnIndex = 1) Then
                    Dim dTemp As Single

                    If (Not Single.TryParse(e.FormattedValue.ToString, NumberStyles.Currency, CultureInfo.CurrentCulture, dTemp) OrElse dTemp < 0) Then
                        MsgBox("La valeur ne doit pas être négative ni être une lettre. Ne laisser pas la case vide non plus.")
                        e.Cancel = True
                    End If
                ElseIf (e.ColumnIndex = 2) Then
                    Dim iTemp As Integer

                    If (Not Integer.TryParse(e.FormattedValue.ToString, NumberStyles.Currency, CultureInfo.CurrentCulture, iTemp) OrElse iTemp < 0) Then
                        MsgBox("La valeur ne doit pas être négative ni être une lettre. Ne laisser pas la case vide non plus.")
                        e.Cancel = True
                    End If
                End If
            End If
            dgvRow.Selected = False
        End If
    End Sub

    Private Sub EnregistrerToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles EnregistrerToolStripMenuItem.Click
        If dSet.HasChanges Then
            Try
                Using con = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source = Mokmeuh.accdb")
                    con.Open()
                    Dim cmb As New OleDbCommandBuilder(dAdapter)
                    dAdapter.Update(dSet.Tables("Articles_Table"))
                End Using
            Catch ex As Exception

            End Try
        End If
    End Sub

    Private Sub AnnulerToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AnnulerToolStripMenuItem.Click
        dSet.RejectChanges()
        DataGridView1.Refresh()
    End Sub
End Class

更多precision

More precision

推荐答案

这是在MenuStrip中和ToolStrip的类缺陷,他们没有正确处理WM_MOUSEACTIVATE通知。这些类有大量的怪癖,他们支持的窗口少的控制,并让他们模仿的确切的相同的行为作为一个正常的Windows窗口从来都不是问题。这些怪癖没有得到解决,的WinForms队拿到了.NET 2.0版本将资源集中用于WPF后不久打破了。

This is a flaw in the MenuStrip and ToolStrip classes, they don't properly handle the WM_MOUSEACTIVATE notification. These classes have plenty of quirks, they support window-less controls and getting them to emulate the exact same behavior as a normal Windows window is never not a problem. These quirks didn't get addressed, the Winforms team got broken up shortly after the .NET 2.0 release to dedicate resources to WPF.

这应该是一个评论,但已经有太多有解决方案显着的, LarsTech 已经想出了一个很好的解决方案。你会发现它在这个答案

This should be a comment but there are already too many to have the solution noticeable, LarsTech already came up with a good solution. You'll find it in this answer.

要做到这一点是VB.NET,用鼠标右键单击您的项目,然后单击添加+级。复制粘贴此code:

To do this is VB.NET, right-click your project and click Add + Class. Paste this code:

Public Class MyMenuStrip
    Inherits MenuStrip

    Protected Overrides Sub WndProc(ByRef m As Message)
        '' Set focus on WM_MOUSEACTIVATE message
        If m.Msg = &H21 AndAlso Me.CanFocus AndAlso Not Me.Focused Then
            Me.Focus()
        End If
        MyBase.WndProc(m)
    End Sub

End Class

点击生成+生成。现在,您将有MyMenuStrip项目在工具箱的顶部。您放到表单上,替换现有的MenuStrip。

Click Build + Build. You'll now have the MyMenuStrip item at the top of the toolbox. Drop it on your form, replacing the existing MenuStrip.

这篇关于MenuStrip中不能专注于负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆