Basically I need to have text within a label, or other container of a given size that can be rotated. But act like a label; the text wraps to next line when it can't fit on one line and is centre aligned.
Looking around I found graphics.DrawString and graphics.RotateTransform I tried messing around with them using some tutorials and managed to rotate text to 90 degrees using this.
Private Sub painted(sender As Object, e As PaintEventArgs) Handles label1.Paint
Dim fontObj As Font
fontObj = New System.Drawing.Font("Times", 10, FontStyle.Bold)
e.Graphics.TranslateTransform(sender.width - 15, 10)
e.Graphics.RotateTransform(90)
e.Graphics.DrawString("Test", fontObj, Brushes.Black, 0, 0)
End Sub
However this doesn't solve the problem of text wrapping and I'm still not entirely sure how exactly this works. I'm looking for a sub that could take parameters of a label control, a string, and a rotation angle(90,180,270) and then draw that string inside the control so that it is all visible without changing the size of the control.
So my question is: is it possible? and if so where do I start and how should I go about it?
Related
Its a bit complicated and I will try my best to explain what I want to achieve.
I've already worked a bit with bitmaps and copy from screen functions.
This all worked very well. But these bitmaps are always rectangles and I would like to use my own bitmap if possible.
As an example:
Somewhere at position x, y on my screen is a map
This map has several paths and junctions.
There are also houses and things that don't interest me, I only focus on the paths in between.
Now I want to scan this map for Argb Pixels using a bitmap and Copy from screen function. I have already done this and it works great, but instead of only scanning the paths for pixels, the whole map is scanned for pixels. But I only want these paths to be scanned.
I have this map as a template and could make a screenshot of it. Can I now import this map into Photoshop, color the houses and everything that I don't need black and make the paths transparent and import them as bitmap so that the Copy From Screen function only scans the paths or is that even possible? I haven't found anything for vb.net if someone could lead me in a right direction I would be very thankful :)
This is the code I got so far - simple pixelsearch function:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim xd3 = Color.FromArgb(255, 100, 100, 100) 'Searching for this color on the screen
Dim b As New Bitmap(2210, 1100) 'Position of Bitmap
Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(b)
g.CopyFromScreen(Me.Left, Me.Top, 0, 0, b.Size) 'Searching on Screen
For i = 0 To (Me.Width - 0) 'searching each pixel
For j = 0 To (Me.Height - 0) 'searching each pixel
If b.GetPixel(i, j) = xd3 Then 'If pixel has same color that im searching for it will show a messagebox true
MessageBox.Show("true")
End If
Next
Next
End Sub
Say for example I draw a box on my screen. The box's X and Y coord will change pretty much all the time. When I am drawing the box and all of it's new position, a new box keeps appearing. I want to draw the same box, and as its location is changed, draw that same box on the new location.
Example :
Box1 : X/Y = 0,0
Box1 (new X/Y) = 0,15
I now have 2 box on my screen.
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim doo As Integer = 1
While doo = 1
For i As Integer = 0 To MonsterCount
Dim xx As Integer = GetPrivateProfileInt("iPC=" & i, "X-Int:", 0, INI)
Dim yy As Integer = GetPrivateProfileInt("iPC=" & i, "Y-Int:", 0, INI)
Box(i) = New Box(xx, yy)
If Box(i).x > -10 And Box(i).y > -10 And Box(0).x <= 1920 And Box(0).y <= 1080 Then
Dim rect As New Rectangle(Box(i).x, Box(i).y, 120, 80)
e.Graphics.DrawRectangle(Pens.Green, rect)
Invalidate()
End If
Next i
Threading.Thread.Sleep(5)
End While
End Sub
That code is very wrong. You need to handle the Paint event of the control you want to draw on and just do your drawing as it should be at that instant. All the data that describes the drawing should be stored in member variables. Any code that changes what needs to be drawn should be outside the Paint event handler. Once it has made changes that need implementing, it should call Invalidate and specify the smallest area that it reasonably can. The next time the control is painted, the Paint event handler will update the drawing and then the invalidated area will be repainted. You might check this out for an example.
In your specific case, you should declare a member variable to store the data required for the box. If the size remains the same then all you need is a Point, otherwise you should keep a Rectangle. Each time the box needs to move, you should store the new value in your field and then call Invalidate twice. The first time you should specify the old Rectangle and the second time you should specify the new Rectangle. By doing that, you ensure that any area that may have changed will be repainted but the rest of the area, which can't have changed, won't be repainted. It's the actual painting to screen, not the drawing code, that is the slow part so you should try to keep that to a minimum. If you really need the repaint done immediately then you can call Update but, otherwise, the new drawing will be displayed the next time the UI thread is free to do so.
I am trying to create a custom UI element: a panel, derived from the original panel, which is scrollable with special scrollbars (not the integrated ones) and has some other special abilities.
The actual problem is the scrolling. When I change the value of the custom scrollbar (e.g. scrolling), the panel-integrated scrollbars show up suddenly, although autoScroll = false.
Leading to the unintended state where both scrollbars are visible, the integrated and my custom one.
Private Sub ScrollB_EvValueChanged(NewVal As Integer) Handles ScrollB.EvValueChanged
Me.CleanPanel1.VerticalScroll.Value = NewVal
End Sub
How can I assign the new scrolling position (the new offset), determined by the custom scrollbar, to the panel without showing up panel-integrated scrollbars?
Sadly a panel (or usercontrol) with another panel on it and playing with the .Top and .Left properties of the inner panel to simulate scrolling is not an appropriate solution in my case.
Thank you for all your hints!
'I've been looking for methods of doing this all over, most of it is way more complicated than it needs to be, or you gotta write a whole dang program just to remove the bars to scroll. Anyhow, here's a quick, effective, neat method of doing this (since I was having trouble finding anything, I'll post it.
'e.delta detects a mouse wheel tick, if greater than 0, scroll up, less than 0 scroll down.
' the -91 part deducts some of the panel overhang (adjust as needed)
'I have buttons in this project that are 50 tall, so this scrolls perfectly for me.
'the nested if statements where there is no code (just else), tells the program to stop 'do nothing if a border is near by. The bottom of my panel, while scrolling, doesn't 'stop when the bottom of the panel (which is hanging off the bottom of the form quite 'some ways) reaches the bottom of the form, this can be adjusted by altering the 700 constant.
Private Sub DaddyPanel_MouseWheel(sender As Object, e As MouseEventArgs) Handles DaddyPanel.MouseWheel
If e.Delta < 0 Then
If (-DaddyPanel.Height - 91) > (DaddyPanel.Location.Y - 700) Then
Else
TextBox1.Text = DaddyPanel.Height & " " & DaddyPanel.Location.Y
DaddyPanel.Location = DaddyPanel.Location + New Point(0, -50)
End If
Else
If DaddyPanel.Location = New Point(0, 0) Then
Else
DaddyPanel.Location = DaddyPanel.Location + New Point(0, 50)
End If
End If
End Sub
After I figured out how to change the different cell's border colors using the RGB values to generate a random color, I now want to change the background color of each cell as well. This is for DataGridView. Below is my relevant code that allowed me to change cell border colors and now somewhere in that code lies a way to change background color of each cell but I am not familiar with this code since it is from a freeware. Does anyone know what I must change in this code to affect the background color of each cell?
Here is my code:
http://pastebin.com/WNBReUys
The solution printing a background color is similar to the pen solution except you need to use a brush, usually a SolidBrush:
Dim brushColor as New SolidBrush(someColor)
e.Graphics.FillRectangle(brushColor ,_
New Rectangle(ColumnLeft(ColPage, ColAt), _
tmpTop, _
ColumnWidth(ColPage, ColAt), _
CellHeight))
Note that since you are drawing text and other graphics on this rectangle, you probably want to paint the background color first, before all the other graphics. (Otherwise, you will end up with only a solid colored rectangle with no text.)
I used the following code to change DataGrid BackColor.
Usually, you assign an array, table or dataset as DataSource of your DataGrid. So, I looped in my DataTable which is my data source, then look for the index of the line I want to change.
Private Sub DataGridForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dgr1.DataSource = TimeDifftbl
dgr1.PreferredColumnWidth = 250
Dim cellText As String
Dim dr As DataRow
For n As Integer = 0 To TimeDifftbl.Rows.Count - 1
dr = TimeDifftbl.Rows(n)
cellText = dr.Item(2)
If cellText = "Tot. RunTime" Then
dgr1.CurrentRowIndex = n
dgr1.Select(n)
dgr1.SelectionBackColor = BackColor.LightGray
End If
Next
End Sub
i am using vb.net 2.0 and i would like to set an icon or image in a DataGridViewButtonColumn. I know the class has no member for it. Anyone has an idea?
Best answer is from http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/b0dfb55c-8bad-4c2d-aa72-36d8c138484e/
But as usual, you Google vb.Net and get answers in C#. I use C# to vb.net tool on the developerfusionwebsite to help me convert to vb.net but usually end up changing a fair amount.
Once you have a pointer this one is quite easy really.
In the dataGridView_CellPainting event add something like this
Private Sub InvoiceLinesDataGridView_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles InvoiceLinesDataGridView.CellPainting
If e.ColumnIndex = 3 AndAlso e.RowIndex >= 0 Then
e.Paint(e.CellBounds, DataGridViewPaintParts.All)
Dim bmpFind As Bitmap = My.Resources.binoc16_h1
Dim ico As Icon = Icon.FromHandle(bmpFind.GetHicon)
e.Graphics.DrawIcon(ico, e.CellBounds.Left + 3, e.CellBounds.Top + 3)
e.Handled = True
End If
End Sub
Just to explain this a little, I wanted to use a resource which is a bitmap so I am converting that to an icon also. This works really well for me and I get a proper button column with an image. The column index is a bit rough as that could change so I was looking to refer using the column name - shouldn't be too hard but you get the idea. SO much easier than the other options I have see around that get you making an extended custom column type.
This really should have just been part of the original control and I cannot fathom why MS crippled the grid so much. I have been trying to use third party controls like Telerik but the originals always seem to be more stable so am now seeing if I can stick with vanilla controls and adding my on extensions where required.
I created a method that can be called in the CellPainting datagridview event.
Public Shared Sub SetImageToDataGridViewButtonColumn_CallInCellPaintingEvent(ByRef img As Bitmap, e As System.Windows.Forms.DataGridViewCellPaintingEventArgs)
e.Paint(e.CellBounds, DataGridViewPaintParts.All & (DataGridViewPaintParts.ContentBackground) & (DataGridViewPaintParts.ContentForeground))
Dim destRect As Rectangle = New Rectangle(e.CellBounds.X + (e.CellBounds.Width - img.Width) / 2, e.CellBounds.Y + (e.CellBounds.Height - img.Height) / 2, img.Width, img.Height)
Dim srcRect As Rectangle = New Rectangle(0, 0, img.Width, img.Height)
e.Graphics.DrawImage(img, destRect, srcRect, GraphicsUnit.Pixel)
e.Handled = True
End Sub
In the CellPainting event, call this method passing the image you want on the button and e. Ensure you use some sort of condition to set on the column you need, this example the If specifies column 0. Also notice I have my image in My.Resources:
Private Sub dgv_CellPainting(sender As Object, e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles dgv.CellPainting
If (e.ColumnIndex = 0 And e.RowIndex >= 0) Then
SetImageToDataGridViewButtonColumn_CallInCellPaintingEvent(My.Resources.myImg, e)
End If
End Sub
Tips: I found 16x16 png were perfect for my use. You can resize using http://images.my-addr.com/resize_png_online_tool-free_png_resizer_for_web.php
You can try using a DataGridViewImageColumn add attach an event to the grid's CellContentClick event (in the event process only the events comming from the column/columns that is/are images)