vb.net中的图形对象
我刚开始在vb.net中创建图形。 我创建了一个windows窗体并双击它。 然后我得到了一个方法,它是表单加载方法。 在这个方法中,我编写了以下代码vb.net中的图形对象,.net,vb.net,gdi+,system.drawing,.net,Vb.net,Gdi+,System.drawing,我刚开始在vb.net中创建图形。 我创建了一个windows窗体并双击它。 然后我得到了一个方法,它是表单加载方法。 在这个方法中,我编写了以下代码 Dim g As Graphics g = Me.CreateGraphics Dim pencolor As New Pen(Color.Red) g.DrawLine(pencolor, 10, 20, 100, 200) 我知道必须在Paint事件中创建图形。 但是我试图在表单加载事件中显示它们。 由于某
Dim g As Graphics
g = Me.CreateGraphics
Dim pencolor As New Pen(Color.Red)
g.DrawLine(pencolor, 10, 20, 100, 200)
我知道必须在Paint事件中创建图形。
但是我试图在表单加载事件中显示它们。
由于某种原因,我没有看到输出
可能是什么问题?。永远不要使用
CreateGraphics
。我认为它实际上没有一个合法的用例
您的问题是,您在表单上绘制了一些内容,但一旦触发表单的下一次重画,它就会被重写,因为您以这种方式创建的图形不会被持久化
您基本上必须使用Paint
事件(或OnPaint
方法)进行绘制,这是无法避免的。如果您想在表单加载中触发重画
,只需调用Me.Invalidate
(但我认为这应该是多余的)
在(或绘制
事件)内,使用参数中提供的图形
对象:
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e) ' First, let the base class do its thing
Dim g = e.Graphics
Using p As New Pen(Color.Red)
g.DrawLine(…)
End Using
End Sub
(请注意,Pen
是一种一次性资源,因此您应该使用块将其包装在中。)尝试以下操作:
Public Class Form1
Dim painted As Boolean = False
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
If Not painted Then
painted = True
e.Graphics.Clear(Color.Blue)
End If
End Sub
End Class
我在VB.net(2010)中扩展了这个不错的答案,以处理DataGridView控件中文本的自动大小调整
首先,将函数修改为:
Private Function MeasureTextWidth(ByVal c As Control, ByVal text As String) As Integer
If (c Is DBNull.Value) Then
Return -1
Else
Dim g As Graphics = c.CreateGraphics
Return CInt(Math.Ceiling(g.MeasureString(text, c.Font).Width))
End If
End Function
在调用此函数的软件中,下一部分如下所示:
With frm_Parameters_FITs
.Show()
With .DataGridView1
.SuspendLayout()
.DataSource = Nothing ' CRITICAL
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeRows = False
.AllowUserToOrderColumns = True
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.ReadOnly = True
.MultiSelect = False
.RowHeadersVisible = False
.Columns.Clear()
.Rows.Clear()
' setup columns
.Columns.Add("Item", "Item#")
.Columns(0).Width = 11
.Columns(0).SortMode = DataGridViewColumnSortMode.NotSortable
.Columns.Add("Parameter", "gHeaderTitle") ' (ColName, HeaderText)
.Columns(1).Width = 25
.Columns(1).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
.Columns(1).SortMode = DataGridViewColumnSortMode.NotSortable
.Columns.Add("ParamValue", "gHeaderInfo")
.Columns(2).Width = 40
.Columns(2).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
.Columns(2).SortMode = DataGridViewColumnSortMode.NotSortable
.Columns.Add("Comments", "gHeaderComment")
.Columns(3).Width = 50
.Columns(3).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
.Columns(3).SortMode = DataGridViewColumnSortMode.NotSortable
.Columns.Add("Comments", "Comments")
.Columns(4).Width = 60
.Columns(4).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
.Columns(4).SortMode = DataGridViewColumnSortMode.NotSortable
.ResumeLayout(True)
End With
'Then you can add the data in rows to the cells of the DataGridView:
Dim piIndex As Integer ' this is a row pointer
Dim ColTextWidth(5) As Integer
Dim TextToMeasure As String
Dim IntTextWidthPixels As Integer
With .DataGridView1
For i As Integer = 1 To Globals.giHeaderLines
.Rows.Add() ' increases the rows.count...the last index is (rows.count-1)
piIndex = .Rows.Count - 1 ' pointer to the last row just added
.Rows(piIndex).Cells(0).Value = i.ToString ' puts this text into the col 0 cell
.Rows(piIndex).Cells(0).Style.WrapMode = DataGridViewTriState.True
.Rows(piIndex).Cells(1).Value = gHeaderTitle(i)
.Rows(piIndex).Cells(2).Value = gHeaderInfo(i)
.Rows(piIndex).Cells(3).Value = gHeaderComment(i)
.Rows(piIndex).Cells(4).Value = gHeaderComment(i)
' now determine the correct col width
For j As Integer = 0 To 4
Try
TextToMeasure = .Rows(piIndex).Cells(j).Value
IntTextWidthPixels = MeasureTextWidth(frm_Parameters_FITs.DataGridView1, TextToMeasure)
If IntTextWidthPixels > ColTextWidth(j) Then
ColTextWidth(j) = IntTextWidthPixels
End If
Catch ex As Exception
Debug.Print("Error here in Class_FileIO_FITs. PutDataIntoHeaderDataGrid")
End Try
Next j
Next i
' now reset the cols to the correct width
For j As Integer = 0 To 4
.Columns(j).Width = ColTextWidth(j)
Next j
End With
'make sure the row we added is visible
.DataGridView1.FirstDisplayedScrollingRowIndex = piIndex
.DataGridView1.ClearSelection()
.DataGridView1.Rows(piIndex).Selected = True
.Refresh()
End With
这可以很好地为DataGridView控件提供正确的宽列。如果您知道应该在Paint
事件中执行此操作,为什么不直接执行呢?我看不出为什么代码应该出现在Load
事件中。我的疑问是,为什么表单加载时,表单上没有显示行。。??我这样做是为了在表单加载时最初画一条线,因为它被Paint
事件覆盖。这就是为什么你应该在那里执行每一个绘图操作。关于样式的一个小提示:在不初始化变量的情况下,永远不要声明变量。前两行应该是一行:Dim g=Me.CreateGraphics()
(使用选项推断)。但无论如何,这是错误的方法(CreateGraphics()
是一个不应该存在的可怕方法)。。??我不明白。。请再解释一下……好的。现在我意识到我别无选择,只能使用paint事件。感谢您指出要在参数列表中使用对象。谢谢你的详细解释。清除了我的疑问。你也可以使用预定义的笔之一pens.Red,而不是创建自己的笔。如果您这样做,不要处理它!“永远不要使用CreateGraphics。我认为它实际上没有合法的用例。”。当然有。首先想到的是MouseMove中的橡皮筋…@DanByström No.您在MouseMove
中跟踪移动和橡皮筋位置,然后通过使控件无效而触发OnPaint
,并在那里执行实际的绘制。关注点分离。这就是我在回答中描述的情况。我不知道为什么CreateGraphics
会存在,但我猜这是因为VB6程序员会有一个快速的脏方法来直接移植代码。不管怎样,我一开始就是这么用的。但是后来我学会了正确地使用WinFormsAPI,我认为恰恰相反。将OnPaint与仅在拖动操作期间使用的易失性绘图代码混在一起对我来说是违反关注点分离的行为。就在前几天,我在一个WinForms项目中实现了一个放大镜,CreateGraphics使代码比我刚从MouseMove调用Invalidate时要干净得多。您实际扩展了什么答案?我不知道,“以上”是,或者很快将是,无用的:答案是按默认投票排序的,这可能会改变。添加一个链接。该贡献将c#代码扩展为VB.net代码。它表明CreateGraphics是可用的,并且使文本宽度度量变得简单。这个问题没有C代码的答案,因此您扩展的任何答案都不在这里。请链接到实际答案,这是基于。