I have 1 picture box, named studPic
. What I want to get is, when I click "shuffle" button, to get random image from resources.
我有1个图片框,名为studPic。我想要的是,当我点击“随机播放”按钮时,从资源中获取随机图像。
private void button2_Click(object sender, EventArgs e)
{
...
}
After research I've found following
经过研究,我发现了以下内容
http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvcs/thread/38d36fa4-1f5f-43e9-80f6-3c9a4edc7705/
I'm newbie to C#.. Is there easier way to achieve this result? For example, without adding picture names?
我是C#的新手..有没有更简单的方法来实现这个结果?例如,没有添加图片名称?
UPDATE
List<string> pictureNames = new List<string>();
pictureNames.Add("1");
pictureNames.Add("2");
pictureNames.Add("3");
int randomPictureIndex = new Random().Next(0, pictureNames.Count);
string randomPictureName = pictureNames[randomPictureIndex];
pictureNames.Remove(randomPictureName);
Image img = Properties.Resources.randomPictureName; //erroor
studPic.Image = img;
getting error message Error 1 'Properties.Resources' does not contain a definition for 'randomPictureName'
获取错误消息错误1'Properties.Resources'不包含'randomPictureName'的定义
3 个解决方案
#1
3
I wouldn't use System Resources for this. They're not as maintainable as the file system for disconnected software.
我不会为此使用系统资源。它们不像断开连接的软件的文件系统那样可维护。
Have your images in a folder for your app. This way they can be updated/changed easily. Say :
将您的图像放在应用程序的文件夹中。通过这种方式,可以轻松更新/更改它们。说:
C:\Ninjas - app
c:\Ninjas\images - images
Create an array that holds these images.
创建一个包含这些图像的数组。
string[] files = System.IO.Directory.GetFiles("c:\ninjas\images");
You'll need to put some filters on the GetFiles to ensure you only get pictures.
您需要在GetFiles上放置一些过滤器,以确保您只获得图片。
Now grab a random position in that array (you've already shown you know how to do random numbers).
现在抓住该数组中的一个随机位置(你已经显示你知道如何做随机数)。
We have the array, let's shuffle it and then you can go through them sequentially (way faster than randomly picking on. CPU will love you for it)
我们有阵列,让它随机播放然后你可以按顺序遍历它们(比随机选择更快.CPU会爱你)
private string[] files;
private int currentIndex = 0;
private void initializeImages()
{
//Grab directories in your images directory
string appRoot = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
files = System.IO.Directory.GetFiles(appRoot + @"\images");
Random rnd = new Random();
files = files.OrderBy(x => rnd.Next()).ToArray();
}
private void setImage()
{
pictureBox1.ImageLocation = files[currentIndex];
}
private void previousImage()
{
currentIndex = currentIndex > 0 ? currentIndex - 1 : 0;
setImage();
}
private void nextImage()
{
currentIndex = currentIndex < files.Length - 1 ? currentIndex + 1 : files.Length - 1;
setImage();
}
A couple things:
几件事:
- Don't hard code the file path. Have this in your app.config file, and reference it.
- 不要硬编码文件路径。在app.config文件中有这个,并引用它。
- You can put the file array global so it doesn't need to be ran each time.
- 您可以将文件数组设置为全局,因此不需要每次都运行它。
If you want to have this as a slide show that runs until the user cancels it I'd recommend the following:
如果您希望将此作为幻灯片放映,直到用户取消它,我建议您使用以下内容:
- Use a timer object that calls a method to increase the image count, which changes the picture.
- 使用调用方法的计时器对象来增加图像计数,从而更改图像。
- Don't use a thread.sleep on your GUI as it will pause your GUI - not a nice thing.
- 不要在GUI上使用thread.sleep,因为它会暂停你的GUI - 这不是一件好事。
If you want to add Next/Previous buttons, you'll need to have a global index (say currentIndex) that can be increased/decreased, then call code to set the image
如果你想添加下一个/上一个按钮,你需要有一个可以增加/减少的全局索引(比如currentIndex),然后调用代码来设置图像
#2
1
Some setup is involved on your part, but the naysayers are mostly right. This is not a very valid solution for a production application. That being said, I doubt this is something you're distributing to tons of people, so we'll call this an academic exercise. If you were to simply add a resource to your application and name it "ImageResource" (any name will do), and add your images to it, you can then use the following code (assuming the corresponding UI elements exist).
您需要进行一些设置,但反对者大多是正确的。对于生产应用程序,这不是一个非常有效的解决方案。话虽如此,我怀疑这是你分发给很多人的东西,所以我们称之为学术练习。如果您只是简单地向应用程序添加资源并将其命名为“ImageResource”(任何名称都可以),并将图像添加到其中,则可以使用以下代码(假设存在相应的UI元素)。
First, we create a function to extract Bitmaps from your resource.
首先,我们创建一个从资源中提取位图的函数。
private Bitmap[] GetResourceImages()
{
PropertyInfo[] props = typeof(ImageResource).GetProperties(BindingFlags.NonPublic | BindingFlags.Static);
var images = props.Where(prop => prop.PropertyType == typeof(Bitmap)).Select(prop => prop.GetValue(null, null) as Bitmap).ToArray();
return images;
}
Second, we create a function that will randomize an image based on the available images:
其次,我们创建了一个函数,可以根据可用的图像随机化图像:
private void RandomizePicture()
{
Bitmap[] images = GetResourceImages();
if (images == null || images.Length == 0)
{
//Nothing to do here...
return;
}
int maxValue = images.Length;
Random r = new Random();
int idx = r.Next(maxValue);
this.uxStupidPic.Image = images[idx];
}
Finally, call that function on a button click:
最后,在按钮上单击调用该函数:
private void btnRandmoize_Click(object sender, EventArgs e)
{
this.RandomizePicture();
}
And voila, randomized images from a resource files. Happy coding!
瞧,来自资源文件的随机图像。快乐的编码!
EDIT: Just noticed you said you were using an Application resource rather than a random resource file. Simply replace "ImageResource" with "Properties.Resources", in GetResourceImages, and you'll be in business.
编辑:刚刚注意到你说你使用的是应用程序资源而不是随机资源文件。只需在GetResourceImages中将“ImageResource”替换为“Properties.Resources”,您就可以开展业务了。
#3
0
I like Ryan Ternier's answer very simple and elegant, I was going to post a solution similar to his.
我喜欢Ryan Ternier的回答非常简单和优雅,我打算发布一个类似于他的解决方案。
I just want to comment on the reasons why line doesn't/shouldn't work:
我只想评论为什么行不/不应该工作的原因:
Image img = Properties.Resources.randomPictureName;
Image img = Properties.Resources.randomPictureName;
- Is because the Properties Resources is looking for a resource called "randomPictureName" rather than the actual name itself.
- 是因为属性资源正在寻找名为“randomPictureName”的资源而不是实际名称本身。
- The way the Properties.Resources object works is that it looks for all your resources in your solution's properties at runtime, after code compilation. It wouldn't work the way you want it to since you're trying to pass in a static variable that may not even exist in resources, forcing you to wrap your method around a try/catch statement just in case.
- Properties.Resources对象的工作方式是在代码编译后,它在运行时查找解决方案属性中的所有资源。它不会按照你想要的方式工作,因为你试图传入一个甚至可能不存在于资源中的静态变量,迫使你围绕try / catch语句包装你的方法以防万一。
http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx
#1
3
I wouldn't use System Resources for this. They're not as maintainable as the file system for disconnected software.
我不会为此使用系统资源。它们不像断开连接的软件的文件系统那样可维护。
Have your images in a folder for your app. This way they can be updated/changed easily. Say :
将您的图像放在应用程序的文件夹中。通过这种方式,可以轻松更新/更改它们。说:
C:\Ninjas - app
c:\Ninjas\images - images
Create an array that holds these images.
创建一个包含这些图像的数组。
string[] files = System.IO.Directory.GetFiles("c:\ninjas\images");
You'll need to put some filters on the GetFiles to ensure you only get pictures.
您需要在GetFiles上放置一些过滤器,以确保您只获得图片。
Now grab a random position in that array (you've already shown you know how to do random numbers).
现在抓住该数组中的一个随机位置(你已经显示你知道如何做随机数)。
We have the array, let's shuffle it and then you can go through them sequentially (way faster than randomly picking on. CPU will love you for it)
我们有阵列,让它随机播放然后你可以按顺序遍历它们(比随机选择更快.CPU会爱你)
private string[] files;
private int currentIndex = 0;
private void initializeImages()
{
//Grab directories in your images directory
string appRoot = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
files = System.IO.Directory.GetFiles(appRoot + @"\images");
Random rnd = new Random();
files = files.OrderBy(x => rnd.Next()).ToArray();
}
private void setImage()
{
pictureBox1.ImageLocation = files[currentIndex];
}
private void previousImage()
{
currentIndex = currentIndex > 0 ? currentIndex - 1 : 0;
setImage();
}
private void nextImage()
{
currentIndex = currentIndex < files.Length - 1 ? currentIndex + 1 : files.Length - 1;
setImage();
}
A couple things:
几件事:
- Don't hard code the file path. Have this in your app.config file, and reference it.
- 不要硬编码文件路径。在app.config文件中有这个,并引用它。
- You can put the file array global so it doesn't need to be ran each time.
- 您可以将文件数组设置为全局,因此不需要每次都运行它。
If you want to have this as a slide show that runs until the user cancels it I'd recommend the following:
如果您希望将此作为幻灯片放映,直到用户取消它,我建议您使用以下内容:
- Use a timer object that calls a method to increase the image count, which changes the picture.
- 使用调用方法的计时器对象来增加图像计数,从而更改图像。
- Don't use a thread.sleep on your GUI as it will pause your GUI - not a nice thing.
- 不要在GUI上使用thread.sleep,因为它会暂停你的GUI - 这不是一件好事。
If you want to add Next/Previous buttons, you'll need to have a global index (say currentIndex) that can be increased/decreased, then call code to set the image
如果你想添加下一个/上一个按钮,你需要有一个可以增加/减少的全局索引(比如currentIndex),然后调用代码来设置图像
#2
1
Some setup is involved on your part, but the naysayers are mostly right. This is not a very valid solution for a production application. That being said, I doubt this is something you're distributing to tons of people, so we'll call this an academic exercise. If you were to simply add a resource to your application and name it "ImageResource" (any name will do), and add your images to it, you can then use the following code (assuming the corresponding UI elements exist).
您需要进行一些设置,但反对者大多是正确的。对于生产应用程序,这不是一个非常有效的解决方案。话虽如此,我怀疑这是你分发给很多人的东西,所以我们称之为学术练习。如果您只是简单地向应用程序添加资源并将其命名为“ImageResource”(任何名称都可以),并将图像添加到其中,则可以使用以下代码(假设存在相应的UI元素)。
First, we create a function to extract Bitmaps from your resource.
首先,我们创建一个从资源中提取位图的函数。
private Bitmap[] GetResourceImages()
{
PropertyInfo[] props = typeof(ImageResource).GetProperties(BindingFlags.NonPublic | BindingFlags.Static);
var images = props.Where(prop => prop.PropertyType == typeof(Bitmap)).Select(prop => prop.GetValue(null, null) as Bitmap).ToArray();
return images;
}
Second, we create a function that will randomize an image based on the available images:
其次,我们创建了一个函数,可以根据可用的图像随机化图像:
private void RandomizePicture()
{
Bitmap[] images = GetResourceImages();
if (images == null || images.Length == 0)
{
//Nothing to do here...
return;
}
int maxValue = images.Length;
Random r = new Random();
int idx = r.Next(maxValue);
this.uxStupidPic.Image = images[idx];
}
Finally, call that function on a button click:
最后,在按钮上单击调用该函数:
private void btnRandmoize_Click(object sender, EventArgs e)
{
this.RandomizePicture();
}
And voila, randomized images from a resource files. Happy coding!
瞧,来自资源文件的随机图像。快乐的编码!
EDIT: Just noticed you said you were using an Application resource rather than a random resource file. Simply replace "ImageResource" with "Properties.Resources", in GetResourceImages, and you'll be in business.
编辑:刚刚注意到你说你使用的是应用程序资源而不是随机资源文件。只需在GetResourceImages中将“ImageResource”替换为“Properties.Resources”,您就可以开展业务了。
#3
0
I like Ryan Ternier's answer very simple and elegant, I was going to post a solution similar to his.
我喜欢Ryan Ternier的回答非常简单和优雅,我打算发布一个类似于他的解决方案。
I just want to comment on the reasons why line doesn't/shouldn't work:
我只想评论为什么行不/不应该工作的原因:
Image img = Properties.Resources.randomPictureName;
Image img = Properties.Resources.randomPictureName;
- Is because the Properties Resources is looking for a resource called "randomPictureName" rather than the actual name itself.
- 是因为属性资源正在寻找名为“randomPictureName”的资源而不是实际名称本身。
- The way the Properties.Resources object works is that it looks for all your resources in your solution's properties at runtime, after code compilation. It wouldn't work the way you want it to since you're trying to pass in a static variable that may not even exist in resources, forcing you to wrap your method around a try/catch statement just in case.
- Properties.Resources对象的工作方式是在代码编译后,它在运行时查找解决方案属性中的所有资源。它不会按照你想要的方式工作,因为你试图传入一个甚至可能不存在于资源中的静态变量,迫使你围绕try / catch语句包装你的方法以防万一。
http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx