C# Use string as a resource name - c#

I'm creating a card game similar to Play Your Cards Right using C# WFA.
I have 52 card faces as PNGs that I want to be able to apply to pictureboxes. I have 10 picture boxes, pbP1Card1 -> pbP1Card5 and pbP2Card1 -> pbP2Card5. When a card is drawn, I want to change the next picturebox from a cardback image to the corresponding card face for the newly drawn card.
I am trying to find a fast solution to getting this to work across all ten PBs. I am thinking of a method similar to this:
string picbox = "pbP1Card1";
string card = "ace_of_spades";
is used in
picbox.Image = Properties.Resources.card
Where the picbox being targeted and the current card can be changed accordingly.
EDIT:
Along with Joe's answer, I have achieved what I wanted by using the following:
picbox.Image = ((System.Drawing.Image)(Properties.Resources.ResourceManager.GetObject(card)));

string picbox = "pbP1Card1";
picbox.Image = Properties.Resources.card
That's not gonna work at all the way you want. Using string values as variable name references is not good practice. Instead, define your PictureBox controls with an array, like this:
PictureBox[,] cards = new PictureBox[1,4];
Now, pbP1Card1 will be cards[0,0]. pbP2Card5 would be cards[1,4], and you can use integer variables to increment through the positions. So you might have a line of code somewhere that looks like this:
cards[0,i].Image = Properties.Resources.card
The best thing here is you don't have to remove and recreate your existing PictureBoxes. Instead, your initialization code has a few lines that look like this:
cards[0,0] = pbP1Card1;
cards[0,1] = pbP1Card2;
cards[0,2] = pbP1Card3;
//...
cards[1,4] = pbP2Card4;
Since PictureBox is a reference type, you will be able to access the same PictureBox object using either reference, so anything you've already written to use the existing names will still work.

Related

Reflecting a picturebox name and a resource picture using a random number

I have 4 picturebox. The names: pb1, pb2, pb3, pb4
And I have 4 resource file: cards_club, cards_diamon, cards_heart, cards_spades
The resource files contains some french card picture. One of the names is: Cards-6-Club.svg
So my problem is: how to reflect them using a random number.
I mean - here is the main part of the code:
Random rnd = new Random();
int color = rnd.Next(1,4+1);
int value = rnd.Next(1,13+1);
int pb_num = rnd.Next(1,4+1);
textBox1.Text=color.ToString()+" "+value.ToString(); //this is just a helper data. It will never show to the user when the program is done
switch (color) {
case 1:
if(value>=2 && value<=10){
pb??.Image = Projectname.cards_club.(Cards_+VALUE+_Club_svg).ToString();
}
My problem is: how can I use the previously generated number (stored as pb_num) here pb??.Image = , where the question mark is. And here Projectname.cards_club.(Cards_+value+_Club_svg).ToString(); how can I combine a previously generated random number (stored as value) with the name of the picture? So with this I can get a picture in the picturebox, where a random number (for example 5) shows the exact card.
If I get 5 (value = 5) I want to show in the picturebox the Cards-5-Club.svg.
Thank you so much your answers, and please feel free to ask if anything is not exactly clear.
**OK, I could solved the problems. :)**
The first one:
"How can I use the previously generated number (stored as pb_num) here pb??.Image = , where the question mark is. "
The answere was soooo obvious (and this was the easier to find it)
I used this question: Name of picturebox
And the answer, witch marked with a thick. (this: https://stackoverflow.com/a/10934094/20290206)
The second one:
"And here Projectname.cards_club.(Cards_+value+_Club_svg).ToString(); how can I combine a previously generated random number (stored as value) with the name of the picture? "
It was hard to find the answere. :/ But I find! :)
I used this question to solve it: How to retrieve Image from Resources folder of the project in C#
And these TWO answers:
This:
https://stackoverflow.com/a/55959810
and that: https://stackoverflow.com/a/32156875
Because I noticed that I use a different way, to create resource files. So, at first I just clicked with right mouse button on the project name on the Solution Explorer, and choose the Add>>New Item option. In the Pop-up window and I choosed the "Resource Files" option.
This was a good method to store the pictures, and reflect them if you preciselly know their name, and you want to use it "just simply". For example if you want to use program integrated pictures when you set the picturebox-content (see the attached picture!).
My wrong method was this (it is not wrong, just not give me the option of calling a specified picture from the resources):
1th pic
2nd pic
BUT the correct way, if you want to reflect to their name is the method which is in the following link, illustrated with picture: https://stackoverflow.com/a/55959810
Then I just mothified this answere:
https://stackoverflow.com/a/32156875
And I can call the picture which contains the random number. :)
So the code which is WORK :
Random rnd = new Random();
int color = rnd.Next(1,4+1);
int value = rnd.Next(1,13+1);
int pb_num = rnd.Next(1,4+1);
textBox1.Text=color.ToString()+" "+value.ToString(); //this is just a helper data. It will never show to the user when the program is done
switch (color) {
case 1:
if(value>=2 && value<=10){
((PictureBox)this.Controls["pb" + pb_num.ToString()]).Image = (Image)Properties.Resources.ResourceManager.GetObject("Cards_" + value + "_Club_svg");
}
I hope this will help someone how struggle with similar problems. :)

Windows Forms Image Resource

Im making a Random Generator with Windows Forms with Images and I use the random pick with resources pictureBox1.Image = Properties.Resources.heart;
Now, the "heart" should get removed from the List, to prevent getting "heart" again.
Here I thought, that I just use int firstCard = randomCard.Next(cards.Count); and I want to use the int firstCard as Properties.Resources.cards[firstCard], because behind Properties.Resources. comes the resource name. But the string doesnt work there, and I dont know how to fix that. Pls help.
Thank you
Pults
Add all your images to a List<Image> - if you have 100 images your list will end up with 100 things
Pick one at random and also remove it. Make the upper bound of random the number of things in the list
//do this once outside the loop that adds images: var r = new Random();
Then the loop that adds images
var x = r.Next(imageList.Count);
var i = inageList[x]; //get the image
imageList.RemoveAt(x); //can't get it again
Note that setting the image of a picture box cannot be done in addition; you'll need multiple picture boxes
Side note, you might find it easier to keep your images in an ImageList (easier to index numerically) - the documentation for it also has some useful/helpful example codes that iteratively draws images into a PictureBox
Also, someone else (maybe doing the same exercise as you :) ) wondered how to get images by string name..
Oh yeah, someone asked the same, didnt find it.
Yea the "ResourceManager.GetObject" is exactly what I needed.
Thanks for the quick response and instant solve!

Measure String in MigraDoc TextFrame

I've already tried asking the question on their forums but as yet to have received a response, hope someone can help me on here.
I have setup a custom report screen in asp.net where people can drag labels and fields and Migradoc produces this accordingly by using textframes and top/left/width/height properties to lay them out in the same place they were dragged/resized to. This all works great however one issue I have is if the text is longer than the textframe it runs off the page and I need the page to move on accordingly whilst retaining the other objects in place.
I can use the below code to measure a string:
Style style = document.Styles["Normal"];
TextMeasurement tm = new TextMeasurement(style.Font.Clone());
float fh = tm.MeasureString(value, UnitType.Millimeter).Height;
float fw = tm.MeasureString(value, UnitType.Millimeter).Width;
But it's only useful for comparing the width against the frame and not the height because it could be different once put into a smaller area. Does anyone know how I can measure this string based on bound width/height values i.e. within a text frame.
Look at the CreateBlocks() method in the XTextFormatter class and how it calls MeasureString in a loop to break the text to multiple lines.
I'm afraid you have to implement such a loop yourself.
Or maybe use the PrepareDocument() method of the DocumentRenderer class to let MigraDoc do the work and just query the dimensions when it's done.
BTW: a similar question had been asked at the forum before:
http://forum.pdfsharp.net/viewtopic.php?p=3590#p3590
Answer includes some source code.
An easy way to do this (using I-liked-the-old-stack-overflow's link) is to add the PdfWordWrapper class to your project and then calculate the dimensions of your text as follows:
var wrapper = new PdfWordWrapper(g, contentWidth); //g is your XGraphics object
wrapper.Add("My text here", someFont, XBrushes.Black);
wrapper.Process();
var dimensions = wrapper.Size; //you can access .Height or .Width
//If you want to reuse the wrapper just call .Clear() and then .Add() again with some new text

Access Form Members with an integer?

In theory the whole thing I'm trying to accomplish is stupid from object orientated point of view,but I have to do it.
Its an Online game I'm working on.The client has an inventory with items,you know - virtual items.
The server sends the items with their corresponding position in the inventory.
This is how my inventory looks like:
I have 62 panels(each panel represents the room in the inventory).
My problem:When I sort out the virtual items and the corresponding slots they should be placed in,I have to draw them on form.
In theory,If I receive item "C:\a.bmp" in position 4,how do I set panel4.image to be equal to the image?
This is what I'm trying to do:
var data = new byte[6];
... //we receive a packet,data is our buffer
var position = data[4];
Form1.panel + position + .backgroundImage = "bla bla.jpg";
How do call the panels like that?
Turn them into an array instead of having 62 individual variables. Then you can use:
Form1.panels[position].BackgroundImage = "...";
There isn't any designer support for this (that I'm aware of) though - did you create all those panels in the designer? If you can possibly do it programmatically instead, you'll make your life a lot easier (IMO).

Are there any OK image recognition libraries for .NET?

I want to be able to compare an image taken from a webcam to an image stored on my computer.
The library doesn't need to be one hundred percent accurate as it won't be used in anything mission critical (e.g. police investigation), I just want something OK I can work with.
I have tried a demonstration project for Image Recognition from CodeProject, and it only works with small images / doesn't work at all when I compare an exact same image 120x90 pixels (this is not classified as OK :P ).
Has there been any success with image recognition before?
If so, would you be able to provide a link to a library I could use in either C# or VB.NET?
You could try this: http://code.google.com/p/aforge/
It includes a comparison analysis that will give you a score. There are many other great imaging features of all types included as well.
// The class also can be used to get similarity level between two image of the same size, which can be useful to get information about how different/similar are images:
// Create template matching algorithm's instance
// Use zero similarity to make sure algorithm will provide anything
ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);
// Compare two images
TemplateMatch[] matchings = tm.ProcessImage( image1, image2 );
// Check similarity level
if (matchings[0].Similarity > 0.95)
{
// Do something with quite similar images
}
You can exactly use EmguCV for .NET.
I did it simply. Just download the EyeOpen library here.
Then use it in your C# class and write this:
use eyeopen.imaging.processing
Write
ComparableImage cc;
ComparableImage pc;
int sim;
void compare(object sender, EventArgs e){
pc = new ComparableImage(new FileInfo(files));
cc = new ComparableImage(new FileInfo(file));
pc.CalculateSimilarity(cc);
sim = pc.CalculateSimilarity(cc);
int sim2 = sim*100
Messagebox.show(sim2 + "% similar");
}

Categories

Resources