打开表单时出现不寻常的故障

时间:2017-06-15 15:18:27

标签: vb.net forms winforms

当我在项目中最大化表单并从中打开另一个表单(使用按钮)时,我遇到了一个不寻常的故障,我只能通过使用下面的屏幕截图来解释。

在此图片中,我有一个订单屏幕和一个货运屏幕。当我点击“添加运费”按钮时,订单屏幕最大化为MDI屏幕,然后在打开货运管理屏幕时,它将两个表单都设置为WindowState.Normal,我正在以编程方式进行操作,我明白为什么它将两种形式设置为正常窗口状态,但是,尽可能地,它会在最大化视图中留下订单屏幕的痕迹。

为了更清楚地说明,表单已从WindowState.Maximized更改为WindowState.Normal,并且在图片中左上角的表单很好,但订单表单仍然显示在两个标准化中并最大化,但最大化的窗口不存在,当你移动其他屏幕时它会消失。

最奇怪的是,我正在使用相同的代码以与程序中其他地方完全相同的方式打开其他窗口,但这种故障并未发生。

只有2个“父”表单在从其中打开其他表单时执行此操作。

还有其他人遇到过这个问题吗?有什么办法吗?即使我在最大化模式下打开另一个表单也会发生这种情况,所以它不像在最大化视图中打开它那么简单。

enter image description here

在示例中打开表单的代码如下:

ugProducts.UpdateData()

  Try
     Dim dt As New DataTable
     dt = ugProducts.DataSource

     Dim ordnum As Integer
     Dim osql As New OleDbCommand
     osql.CommandType = CommandType.Text

     osql.Connection = con
     osql.CommandText = "SELECT [Order_Number] FROM [Order_Freight] WHERE [Order_Reference] = ?"
     osql.Parameters.AddWithValue("@onum", lblReference.Text.ToString)

     ordnum = Convert.ToInt32(osql.ExecuteScalar)

     Dim ORef As String
     ORef = lblReference.Text

     Dim FNumber As Integer

     Dim fsql As New OleDbCommand
     fsql.CommandType = CommandType.Text

     fsql.Connection = con
     fsql.CommandText = "SELECT [Freight_Number] FROM [Order_Freight] WHERE [Order_Reference] = ?"
     fsql.Parameters.AddWithValue("@fnum", lblReference.Text.ToString)

     FNumber = Convert.ToInt32(fsql.ExecuteScalar)

     Dim PC As String
     Try
         PC = ugProducts.ActiveRow.Cells("Product_Code").Text.ToString
     Catch
         PC = ugProducts.Rows(0).Cells("Product_Code").Text.ToString
     End Try

     Dim SC As String
     Try
         SC = ugProducts.ActiveRow.Cells("Supplier_Code").Text.ToString
     Catch
          SC = ugProducts.Rows(0).Cells("Supplier_Code").Text.ToString
     End Try

     Dim f As New frmEditFreight(con, dt, Me, cmbCustCode.Text, ordnum, ORef, FNumber, PC, SC)
     f.MdiParent = Me.MdiParent
     f.Show()

 Catch ex As Exception
     errorLog(ex)

 End Try

然后,在加载的表单上,我有这个

   Me.Location = New Point(0, 0)
    Me.WindowState = FormWindowState.Normal

    txtTotal.ReadOnly = True
    lftable = New DataTable

    If isNewOrder = False Then
        Try
            For Each dc As DataColumn In lineTable.Columns
                If dc.ColumnName = "Order_Number" OrElse dc.ColumnName = "Product_Code" OrElse dc.ColumnName = "Supplier_Code" Then
                    lftable.Columns.Add(New DataColumn(dc.ColumnName, dc.DataType))
                End If
            Next

            Dim product As String = ""
            Dim supplier As String = fOrder.cmbSupplier.Text

            Dim ds As New DataSet

            Dim da As New OleDbDataAdapter("SELECT * FROM [Order_Freight] WHERE [Order_Number] = ?", con)
            da.SelectCommand.Parameters.Add("@num", OleDbType.Integer).Value = orderNum
            da.Fill(ds)
            Dim nDt As New DataTable
            nDt = ds.Tables(0).Copy()

            For Each row As DataRow In nDt.Rows
                product = row.Item("Product_Code")

                For Each dr As DataRow In lineTable.Rows
                    If dr.RowState <> DataRowState.Deleted Then
                        If dr.Item("Product_Code") = product Then
                            dr.Delete()
                        Else
                        End If
                    Else
                        If dr.Item("Product_Code", DataRowVersion.Original) = product Then
                            dr.Delete()
                        Else
                        End If
                    End If
                Next
            Next

            For Each dr As DataRow In lineTable.Rows
                If dr.RowState <> DataRowState.Deleted Then
                    dr.Item("Order_Number") = orderNum
                End If
            Next

            Me.ugProducts.DataSource = lineTable

            For Each dc As UltraGridColumn In ugProducts.DisplayLayout.Bands(0).Columns
                Dim cName As String = dc.ToString

                Select Case cName
                    Case "Product_Code"
                        dc.Hidden = False
                    Case "Order_Number"
                        dc.Hidden = False
                    Case "Supplier_Code"
                        dc.Hidden = False
                    Case Else
                        dc.Hidden = True
                End Select
            Next

            loadAddresses(custCode, con)

            dtEstDelivery.Value = Date.Today

            ugProducts.DisplayLayout.Bands(0).Override.CellClickAction = CellClickAction.RowSelect

            selectedTable.Columns.Add("Product_Code")
            selectedTable.Columns.Add("Supplier_Code")
            selectedTable.Columns.Add("RowIndex")

            freightTable = New DataTable

            With freightTable.Columns
                .Add("Freight_Number")
                .Add("Address_Code")
                .Add("Est_Delivery")
                .Add("Product_Code")
                .Add("Freight_Desc")
                .Add("Freight_Val", GetType(Decimal))
                .Add("Supplier_Code")
                .Add("freeDelivery", GetType(Boolean))
            End With

            ugFreight.DataSource = freightTable

            ugSelected.DataSource = selectedTable
            ugSelected.DisplayLayout.Bands(0).Override.CellClickAction = CellClickAction.RowSelect

        Catch ex As Exception
            errorLog(ex)

        End Try
    Else
        Try
            Me.ugProducts.DataSource = lineTable

            For Each dc As UltraGridColumn In ugProducts.DisplayLayout.Bands(0).Columns
                Dim cName As String = dc.ToString

                Select Case cName
                    Case "Product_Code"
                        dc.Hidden = False
                    Case "Product_Description"
                        dc.Hidden = False
                        dc.Header.Caption = "Description"
                    Case "Supplier_Code"
                        dc.Hidden = False
                        dc.Header.Caption = "Supplier"
                    Case Else
                        dc.Hidden = True
                End Select
            Next

            loadAddresses(custCode, con)

            dtEstDelivery.Value = Date.Today

            ugProducts.DisplayLayout.Bands(0).Override.CellClickAction = CellClickAction.RowSelect

            selectedTable.Columns.Add("Product_Code")
            selectedTable.Columns.Add("Supplier_Code")
            selectedTable.Columns.Add("RowIndex")

            freightTable = New DataTable

            With freightTable.Columns
                .Add("Freight_Number")
                .Add("Address_Code")
                .Add("Est_Delivery")
                .Add("Product_Code")
                .Add("Freight_Desc")
                .Add("Freight_Val", GetType(Decimal))
                .Add("Supplier_Code")
                .Add("freeDelivery", GetType(Boolean))
            End With

            ugFreight.DataSource = freightTable

            ugSelected.DataSource = selectedTable
            ugSelected.DisplayLayout.Bands(0).Override.CellClickAction = CellClickAction.RowSelect

        Catch ex As Exception
            errorLog(ex)

        End Try
    End If

    bLoading = False

接下来是一些普通的东西,设置DataTables,加载数据等

有问题的另一种形式有这个代码:

 Try
    Dim grid As UltraGrid = DirectCast(sender, UltraGrid)
    Dim lastElement As UIElement = ugRates.DisplayLayout.UIElement.LastElementEntered
    Dim rowElement As RowUIElement

    If TypeOf lastElement Is RowUIElement Then
         rowElement = DirectCast(lastElement, RowUIElement)
    Else
         rowElement = DirectCast(lastElement.GetAncestor(GetType(RowUIElement)), RowUIElement)
    End If

     If rowElement Is Nothing Then Return

     Dim row As UltraGridRow = DirectCast(rowElement.GetContext(GetType(UltraGridRow)), UltraGridRow)

     If (row Is Nothing) Then Return

     Dim MousePosition As Point = grid.PointToClient(Control.MousePosition)

     If Not lastElement.AdjustableElementFromPoint(MousePosition) Is Nothing Then Return

 Select Case row.Cells("cType").Value
     Case "Acquisition Rate"
       Dim supplier As String

       If rbtnAllSuppliers.Checked = True Then
          supplier = row.Cells("Supp_Code").Value
       Else
          supplier = cmbSupplier.Text
       End If

       Dim f As New frmCommission(con, row.Cells("Comm_Code").Value, supplier, True)
       f.MdiParent = Me.MdiParent
       f.Show()

以下选择案例的其余部分。在这种情况下打开的表单然后有代码

  Me.Location = New Point(0, 0)
  Me.WindowState = FormWindowState.Normal
  Me.Cursor = Cursors.Default

  isUpdate = False

  Me.ugComm.ContextMenuStrip = cmCommRate

  With updateDT.Columns
      .Add("Apply", GetType(Boolean)).DefaultValue = False
      .Add("Product_Code")
      .Add("Commission_Rate")
      .Add("Multiplier")
  End With

  btnCustomerSearch.Enabled = False

  Try
      Dim da As New OleDb.OleDbDataAdapter
      Dim ds As New DataSet

      sql = "SELECT * FROM [System Settings]"
      da = New OleDb.OleDbDataAdapter(sql, con)

      Dim dt As New DataTable
      da.Fill(dt)

      If dt.Rows(0).Item("enableAqDate") = False Then
          rbtnAcq.Enabled = False
      End If

      If cCode <> "" And sCode <> "" Then
          cmbSupp.Text = sCode
          cmbSupp_ValueChanged(sender, New EventArgs)
      End If

      disableControls()

      cmbSupp.Refresh()
      txtCommCode.Refresh()
      ugComm.Refresh()
      cmbSupp.Enabled = False

      isLoad = False

      If isEnquiry = True Then
          txtCommCode.Text = cCode
          loadEnquiry()
          ugComm.Enabled = True
          cmdAddRange.Enabled = False
          cmdUpdateRange.Enabled = True
          cmbSupp.Value = sCode
          txtCommCode.Text = cCode
      End If

  Catch ex As Exception
      errorLog(ex)

  End Try

在尝试插入建议用于制作dpiaware = True的代码时,我无法在代码中看到这样的内容吗?

enter image description here

1 个答案:

答案 0 :(得分:4)

当有效的mdi子窗体最大化时,罪魁祸首似乎是将WindowState属性设置为mdi子窗体的Normal事件中的Load属性。

此时目标表单处于某种中间状态 - 事件作为窗口句柄创建的一部分被调用,句柄已经创建,Visible属性为True(但表单是屏幕上没有真正显示),WindowState会返回Maximized,并尝试将其设置为Normal内部导致ShowWindow API调用。

很难确定错误的确切位置(Form类中有很多内部标记和窗口消息处理),但最终结果是MDIClient和当前活动mdi子窗体未正确无效,因此您正在经历视觉效果。

话虽如此,有几种解决方法:

(1)在侧面显示的表格中:

Me.WindowState = FormWindowState.Normal移至Shown事件。

(2)在来电方:

(A)在Me.WindowState = FormWindowState.Normal

之前添加f.Show()

(B)在Me.MdiParent.Invalidate(True)

之后添加f.Show()

(C)在Me.MdiParent.Refresh()

之后添加f.Show()

我个人的偏好是选项(1),因为它封装了一个逻辑,该逻辑特定于该表单中的被调用表单。