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. :)
Related
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!
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.
I have a very strange problem that I never been in touch with in my entire life.
This is what I been up to:
I have programmed a game that involves you going to throw two dices and the sum of the two dices should be seven for you to win.
This is how the interface is built:
The textbox1 shows the value of first thrown dice.
The textbox2 shows the value of second thrown dice.
The textbox3 shows the sum of the both dices.
The button1 throws the dices.
This is the problem:
When i Debugg (F5) the application in Visual Studio 2013 Ultimate
the textboxes gets the exactly same value all the time. This is wrong, it shouldn't act like this.
When i Step Into (F11) the application/code the textboxes gets
different values, just as it should be, this is right, this is how the program should act.
Is there anyone that can help with this problem, i think that I have just missed a very small but a obvious thing that I have missed but I really can't find anything, I'm actually out of ideas!
Attachments
Here is all the files, I hope it will help you, the program is written in Swedish but I don't think that makes any problem, if it do, I can translate the whole solution to English.
The whole Solution: Throw_Dices.zip
The Code: Big picture on three screens of the code
From MSDN:
different Random objects that are created in close succession by a
call to the default constructor will have identical default seed
values and, therefore, will produce identical sets of random numbers
In your Kasta.cs, create a static instance of Random instead of multiple ones.
public class Tarning
{
private static Random ran = new Random();
int slump;
public int Kasta()
{
//Random ran = new Random();
slump = ran.Next(1, 6);
return slump;
}
}
Another possibility would be to create a seed manually. For instance like
public int Kasta()
{
byte[] seed = new byte[4];
new RNGCryptoServiceProvider().GetBytes(seed);
int seedInt = BitConverter.ToInt32(seed, 0);
Random ran = new Random(seedInt);
slump = ran.Next(1, 6);
return slump;
}
Instead of creating two Dice (Tarning ?)
Create one and roll it twice.
Or create both on start up, Or perhaps have a class that holds 2 dice.
and throw them again.
You should also google random and seeding, what's happening is from the same seed value, you get the same sequence of random numbers. Debugging is introducing enough of a delay between the new Random calls, that the seed (based on the clock) has changed between the two calls.
PS your button1Click handler
should set the three textbox values, not trigger textbox changed events which then set them. Imagine if you wanted to reuse your code, you'd have to create a UI to do it.
A better way would be to have a class that held two (or n) dice with a Roll method and a property that returned the result. Then you could reuse it without worrying about when and how.
I am trying to write a kiosk program for my print center at a school for students to select size and media type and then have it generate a price. I am currently doing this with radio buttons which works fine but we are adding many more options and a drop down list box would be more appropriate. Also, my code for calculating the price is out of control. I would like to set this up so that calculating the price should be easy. Setup is something like this:
File1 - Paper Size (9 options) - Media Type (18 options)
File2, File 3, etc.
I was going to store this in a 3D array filename[]papersize[]media[] for processing the price.
The problem is that not all media types are available in all sizes. I see that you can not disable items in the list. If you pick one size, I can selectively populate the other drop down with or without items, but it changes my index numbers. If I could disable items, I could keep the same index and make an easy loop for processing prices. As it is now I would have to manually specify and loop for each paper size since the media types are different indexes.
I hope this makes sense, I am not really a programmer, I am just trying to make something simple to improve our workflow and accuracy at the print center. I can provide a screen shot of the old program and a mockup of my new program if it would help. Can anyone think of a more elegant solution for this?
Thanks!!
EDIT
Yikes.. Ok, this is ending up to be more difficult than I was expecting: Thanks everyone for your input, it is much appreciated. I did not really expect any responses and there were a lot. Thank You. I attempted the table idea mentioned below but I am not exactly sure how to implement it. I will comment on that post for what I tried. Let me provide more detail in the event that someone else has another idea.
For example of what I am trying to do:
Size = 8.5x11 has media = matte, double sided matte, luster, gloss, acetate, resume
Size = 11x17 has media = same minus acetate and resume
and so on, up to a 60" roll with backlit media and all sorts of stuff.
Price for 8.5x11 is 1.50 regardless of paper and then each paper has its own price
Price for 11x17 is 3.00 and each paper has its own price which is more than their 8.5x11 counterparts
8.5x11 matte = .25
11x17 matte = .50
8.5x11 matte total = 1.75
11x17 matte total = 3.50
I am trying to do this in as little steps as possible. Currently I have radio buttons which take up a bunch a screen real-estate and do things like: When 11x17_1.Checked acetate_1.Disable, etc. Also for calculating price I have hundreds of lines of code doing things like:
If(8.5x11_1.Checked)
{
If(matte_1.Checked)
price = 8.5x11matte_1;
if(luster_1.Checked)
price = 8.5x11luster_1;
...etc.
}
Rolls require more data (height) to be processed as we charge by linear inch for these. Currently for each file I just have a height box that they are required to fill out. I could just put a height field next to each file for my new version. Then if they select a roll, the height box bust be filled out, which requires more IF's... which I currently have hundreds of. Any thoughts on a more elegant way to do this?
I just don’t have the programming background to simplify this, but I know this can probably be done in 10 lines of code using an array and drop down lists:
It has been a long time since I used arrays but I was thinking of something like:
Selection[file_1][combobox_size.Index][combobox_media.Index]
I think I would have to manually define each array value since the prices are arbitrary?
[0][0][0] = 1.75
[0][0][1] = 1.75
[0][0][2] = 2.00
And so on.
My winform would have let’s say 12 rows for them to enter a file name and then pick the drop down lists. If filename != null then I will process a price for the file and selections.
So if file 1 was 11x17 gloss my array would be something like:
[0][1][3] which I would have pre-defined with a value of $4.00 for example
If it is a roll then I would just multiply by the required height box.
Is this logic sound or grossly inefficient?
EDIT #3
Ok, almost there I think. Sadly, I was unable to figure out the other solutions offered by the community, but I wrote a "get_index" function that looks like this:
public static int get_index(string index)
{
if (index == "Matte")
return (1);
....
if (index == "Luster")
return (3);
....
else
return (0);
}
in my main program I define prices like this:
for (int x = 0; x < filenum; x++)
{
pricegrid[x, 0, 0] = 1.75; // 8.5x11 Resume
pricegrid[x, 0, 1] = 1.75; // 8.5x11 Matte
pricegrid[x, 0, 2] = 1.75; // 8.5x11 Double Sided Matte
pricegrid[x, 0, 3] = 2.35; // 8.5x11 Luster
.....
}
Then to calculate the price I am doing something like this calling that get_index function:
private void calculate_price()
{
getindex[0] = get_index(media1.SelectedItem.ToString());
....
}
You should populate your ComboBox dynamically as you do.
Instead of using SelectedIndex you can use SelectedValue which does not depend on number of elements.
See for example: Using ValueMember in ComboBox
You shouldn't use one three-dimensional array. You will need 3 tables to that. Store all your types in a database.
3 tables are:
1. paper
2. media
3. papermedia
so. you populate first dropdown with papersizes.
then when item is selected in papersizes you run a query to populate dropdown media (you join through intersection table). this way you will only show media that is only available for this papersize. or you can do the other way around.
Does this answer your question?
There are several ways of doing it.
You could create a class FileWithDetail that'd store
[class File / class paper size / class Mediatype ]
Initialize your list at the start of your app
List<FileWithDetail> LstFileWithDetail = new FileWithDetail(){...}
Then with Linq to Object you would easily be able to query the object and bind it to your comboboxes according to your selected value
var LstPaperSize = from p in FileWithDetail
where p.FileName == SelectedFileName
Select ...
I want to provide the user with a selection of questions but I want them to be random, having a quiz game with the same questions isn't exactly fun.
My idea was to store a large collection of questions and there appropiate answers in a text file:
What colour is an Strawberry|Red
How many corners are there on a Triangle|Three
This means that I could simply select a line at random, read the question and answer from the line and store them in a collection to be used in the game.
I've come up with some pseudo code with an approach I think would be useful and am looking for some input as to how it could be improved:
Random rand = new Random();
int line;
string question,answer;
for(int i = 0; i < 20; i++)
{
line = rand.Next();
//Read question at given line number to string
//Read answer at given line number to string
//Copy question and answer to collection
}
In terms of implementing the idea I'm unsure as to how I can specify a line number to read from as well as how to split the entire line and read both parts separately. Unless there's a better way my thoughts are manually entering a line number in the text file followed by a "|" so each line looks like this:
1|What colour is an Strawberry|Red
2|How many corners are there on a Triangle|Three
Thanks for any help!
Why not read the entire file into an array or a list using ReadLine and then refer to a random index within the bounds of the array to pull the question/answer string from, rather than reading from the text file when you want a question.
As for parsing it, just use Split to split it at the | delineator (and make sure that no questions have a | in the question for some reason). This would also let you store some wrong answers with the question (just say that the first one is always right, then when you output it you can randomize the order).
You don't want to display any questions twice, right?
Random random = new Random();
var q = File.ReadAllLines("questions.txt")
.OrderBy(x=>random.Next())
.Take(20)
.Select(x=>x.Split('|'))
.Select(x=>new QuestionAndAnswer(){Question=x[0],Answer=x[1]});