I am making a board game and want to store information about each square of a 10x10 grid inside a structure, and I need to get the entire array rects from the record structure squares and use it in e.Graphics.FillRectangles(). Everything apart from the declarations are inside a paint event.
Public Structure squares
Dim rects As Rectangle
End Structure
Dim s(99) As squares
'assigning values to each instance of rects
e.Graphics.FillRectangles(b1, s.rects)
e.Graphics.DrawRectangles(p1, s.rects)
but this gives the error 'rects' is not a member of 'Form1.squares()'. s().rects does not work either. Note that I am not trying to get a specific index, as FillRectangles does not accept it as an argument.
I previously had rects on its own and that worked without any issues.
Dim rects(99) as Rectangle
'assigning values to each instance of rects
e.Graphics.FillRectangles(b1, rects)
e.Graphics.DrawRectangles(p1, rects)
I could use a loop that draws each rectangle individually, but I found that this method is much slower and not what i'm looking for.
Is there any way to make this work or should I have it as an array on its own and only store other information inside the structure? Should I even use a structure at all or would using parallel arrays be a better idea?
You cannot call s.rects. There is not an index to extract rects. That must be s(indexHere).rects.
However the code below return all rects from your array:
Dim s(99) As squares
'Do not forget to set rects before calling those two
e.Graphics.FillRectangles(Brushes.Red, s.Select(Function(x) x.rects).ToArray)
e.Graphics.DrawRectangles(Pens.Black, s.Select(Function(x) x.rects).ToArray)
Related
In Vb.Net, I'm dinamycally creating several textbox and labels. I'm naming them ex. VLabel1, VLabel2, VLabel3 ... and then I use CType and a variable to use them.
Dim VarName as String
Dim i as Integer
Dim MyLabel as Label
i=0
VarName = ("VLabel" & i.ToString)
MyLabel = CType(Panel1.Controls(VarName), Label)
Now I'm adding lines using LineShape (I can't use label having height of 1 because my lines are diagonals). Can I use a similar way to select a specific line or do I have to use a loop in my ShapeContainer and compare names until I find the one I want?
Thank you,
Stephane
do I have to use a loop in my ShapeContainer and compare names until I find the one I want?
What do you think the Controls(VarName) does? It has to lookup the control by name, too. If you're comfortable with that, you can write a method in your form that does the same thing.
But a better option for both the LineShapes and the Labels is use List(Of LineShape) and a List(Of Label). When you create a dynamic control and add or remove it from your form, also add or remove it form your list. Then you can reference these items by index, without needing to build a name string. You'll also have less casting this way.
Another option to index them by name is to use Dictionary(Of String,Lineshape) and Dictionary(Of String, Label). A couple of helper subs can handle adding/removing where needed and adding/removing to the appropriate Dictionary. With this you also eliminate the need for casting as the actual objects are of the correct type already.
Even better yet, since Shapes aren't part of the standard library, I would suggest learning how to draw the lines directly on to your form.
I've never done it, but it should be possible to actually create the lines as controls, by creating a class that inherits from the Control class and overriding the Paint sub to draw the line.
I have a problem with the function IntersectWith
I have used this function with VBA and it has a option Intersect.None
But when I call the function from VB.NET this option does not exist.
I try to use the available options but all detect an incorrect intersection
yourCADObjectII.IntersectWith(myText, Intersect.ExtendBoth, points, New IntPtr(0), New IntPtr(0))
yourCADObjectII.IntersectWith(myText, Intersect.OnBothOperands, points, IntPtr.Zero, IntPtr.Zero)
yourCADObjectII.IntersectWith(myText, Intersect.ExtendArgument, points, IntPtr.Zero, IntPtr.Zero)
yourCADObjectII.IntersectWith(myText, Intersect.ExtendThis, points, IntPtr.Zero, IntPtr.Zero)
I don't know how to use IntersectWith in VB.NET as I used in VBA with the Intersect.None option.
I tried to detect a text string vs. a closed polyline, the text is inside of a polyline, I want to detect if the text intersects with the LWPolyline.
The text has different rotations and the polyline has different geometry.
As far as know, the COM/ActiveX IntersectWith method does not have any Intersect.None option. It has a acExtendNone option whose .NET equivalent is Intersect.OnBothOperands.
COM .NET
acExtendNone Intersect.OnBothOperands Does not extend either object.
acExtendThisEntity Intersect.ExtendThis Extends the base object.
acExtendOtherEntity Intersect.ExtendArgument Extends the object passed as an argument.
acExtendBoth Intersect.ExtendBoth Extends both objects.
I think you are implementing IntersectWith correctly and your problem is not with what you mentioned. From memory, when you try to use intersectwith for DBText with any other object, it doesn't actually calculate the intersection with the text itself but rather with its bounding box. And that bounding box doesn't always fit the text exactly. It sometimes is bigger than the text (depending on rotation). Or sometimes it is smaller than the text especially when using letters like (y, j, q,g, etc...)
So your best bet is to try and find the bounding box that fits your rotated text by finding the bounding box that fits the same text with no rotation then rotate that box (using a closed polyline to capture all 4 corners)
Now your problem becomes intersection of two polylines instead of text and polyline. And then you can use intersectWith to get intersection points
I made this boolean array.
I want change the color of first boolean component as red, and second as blue.
This picture is what I want.
But when I change color property, three booleans change their color with together.
Is there any way to change color of boolean components, respectively?
Short answer: Just replace the boolean with a color box, as shown in the links in the other reply. It will simply be an array of color boxes instead of an array of booleans.
Long answer: An Array control contains an inner element control. The only property that can differ between elements of the array is the Value property. All other properties are rendered identically across elements of the array. If you need to differentiate the elements based on something other than the Value, you need to either use a different control that renders the graphical aspect that you want as its Value (i.e. replacing the Boolean with a Color Box) or you need to break out the N elements that you want to display as N separate independent controls and manage the updating of the display by yourself through code on the block diagram. This generally means creating your own scrollbar control or numeric control for controlling the index of the array.
You can always try to change your approach a little, try using clusters and if you need to use array, then create array of clusters. Here and here are similar subjects that should help you solving the problem with colors.
First things first. There's a good chance what I want to do should really be done with VB and not VBA. But as long as it is possible I would rather use VBA.
I have a userform of essentially a big diagram made of hundreds of labels. I want to separate these labels into groups. And then separate these groups into subsystems. The idea being I have some form of heirarchy to work with. The label groups need to change color based on what I have selected in a combo box, and if I click on one of these labels I want to bring up a user form showing details of the subsystem using click events.
I'm pretty sure I need to use multiple classes to do what I want but am fairly new to using class modules. Though I get the concept.
Basically I want some functionality that goes subsystem -> label group( or part) -> color with click events for the whole subsystem and combo box events for changing label group colors.
I saw a thread online about grouping labels or text boxes but it only works to trigger the even for a group, not change the properties of the whole group once the event is triggered. I would like to set this up in classes as well so I can export the system for use in other future userforms.
I was able to create groups of labels and change them together like I wanted:
CPart (Class Module 1):
*This is meant to handle the event triggering of the labels and includes some color code that I used to test functionality of the groups changing together and functionality of changing colors.
Public WithEvents trigger As MSForms.Label
Dim pLabels As Collection
Property Set triggers(c As Collection)
Set pLabels = c
End Property
Private Sub trigger_Click()
For Each obj In pLabels
obj.BackColor = RGB(255, 0, 0)
Next obj
End Sub
CTrigger (Class Module 2):
*This took a collection of labels which were passed in through a collection variable in the userform and then stored each label as a trigger in a separate class variable, along with the whole collection of labels in that group. This way when any trigger fires the event, all of the labels change.
Dim CTrigger() As New CPart
Dim pLabels As Collection
Dim i As Integer
Property Set Labels(c As Collection)
Set pLabels = c
For i = 1 To pLabels.Count
ReDim Preserve CTrigger(1 To i)
Set CTrigger(i).trigger = pLabels.Item(i)
Set CTrigger(i).triggers = pLabels
Next i
End Property
Property Get Labels() As Collection
Labels = pLabels
End Property
I really don't like the way it works, partly because I am losing myself in the logic of it constantly, and partly because it means that in order to use this I have to make collections of labels in the userform module anyway just to run it. It is very inefficient code, but I am putting it up so you get an idea of what I am trying to accomplish.
What I would much rather do instead is have one class variable to hold my custom collection of labels (a "LabelGroup"). Another class variable is likely required to hold the labels themselves (I think). And then all I would have to do is go through and write methods for the LabelGroup class such as changecolor, and it could handle that. But I can handle that part, for now what I really need help with is setting up the class framework in a neat way, so that the module I will eventually run could just say things like:
LabelGroup1.Add Label1
LabelGroup2.Add Label2
or
Private Sub button_click()
LabelGroup1.ChangeColor(RGB(...))
End Sub
These two articles have been helping me along:
http://www.databaseadvisors.com/newsletters/newsletter200503/0503usingcustomcollections/using%20custom%20collections%20in%20microsoft%20access.asp
http://j-walk.com/ss/excel/tips/tip44.htm
I was just looking at something similar but not quite so detailed. I'm trying to improve the look of a complex userform by making it look more modern and was going to try to fake mouseOver highlighting or at least active/inactive shading for labels placed overtop of graphical buttons.
Anyway, have you considered just changing the names of the label objects so that they are prefixed/suffixed with some kind of group or subsystem ID?
That way when you pass them to a sub to change their colour, you can check the prefix or suffix.
I am currently in the process of making a snake game using VB.NET... I was just wanting to gather ideas on how to do the body of the snake...
Currently I have a class called SnakeBody which contains the following code:
Public Class SnakeBody
Dim yCoord As Integer
Dim xCoord As Integer
Dim body As PictureBox
End Class
I guess what I am asking is if Dim body As PictureBox a logical thing to put in my class. As in, I am not sure if that is the correct thing to do? To create the actual body of the snake I will have an array of these SnakeBody objects.
If `'Dim body As PictureBox is valid How do I reproduce the same picturebox everytime my snake eats something?
I hop this makes sense... Thanks Alot
Well, it is okay but it is not going to work well in practice. PictureBox is a window, when snakes overlap each other, you'll obscure part of them with a rectangle. You'll essentially see one snake in a rectangle with bits of other snakes peeking out past that rectangle.
Use the form's Paint event to draw the snakes, don't use a control.
Don't use Winforms. Use vb.net and silverlight, you can design a template for the snake , you have silverlights sophisticated built in animation. It will be so much easier and better and it will run on a PC and Mac.
actually i don't know how to add a cube when the snake eat something
try to use System.drawing.graphics to draw cubes ( parts of the snake ) : it's a bit easier
if you want to make the snake moving you should make a script based on this :
REMEMBER : THIS IS ONLY A DIMOSTRATION OF WHAT HAVE THE CODE TO DO :
Dim CubeSelected as integer = 1 ' Selected cube
loop {
if right_key_pressed{
' You have to make this command : cube(number of the cube , direction)
cube(CubeSelected,right) ' Change the selected cube direction
MoveSelect = MoveSelect + 1 ' Select the next cube
Threading.Thread.Sleep(500) ' Wait
}
}
if you press the right key , the cubes will change the direction one for time .
So the snake will make a curve and proceed to the right direction
it's a little more complicated actually , but i hope it helps