Displaying several random images in several Image Controls from a folder without repeating in WPF?

رضا جافری 1,296 Reputation points
2021-06-05T11:25:15.19+00:00

First and foremost, I apologize for my grammatical errors; my first language is Persian (Iran).
I have 30 images (*.png) that i want to display randomly in 30 Image Control.
I wrote the following codes but ...

XAML codes

<GroupBox x:Name="ImageGroupBox" Header="Image Recognition" Margin="10,38,0,0" HorizontalAlignment="Left" Height="423" VerticalAlignment="Top" Width="335">  
        <ItemsControl x:Name="ImageItemsControl" Margin="-6,-16,0,0" Height="423" Width="335" HorizontalAlignment="Left" VerticalAlignment="Top">  
            <Grid x:Name="ImageGrid" Margin="0,0" Height="423">  
                <Image x:Name="Image0" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="13.5,35,0,0"/>  
                <Image x:Name="Image1" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="75.5,35,0,0"/>  
                <Image x:Name="Image2" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="137.5,35,0,0"/>  
                <Image x:Name="Image3" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="199.5,35,0,0"/>  
                <Image x:Name="Image4" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="261.5,35,0,0"/>  

                <Image x:Name="Image5" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="13.5,97,0,0"/>  
                <Image x:Name="Image6" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="75.5,97,0,0"/>  
                <Image x:Name="Image7" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="137.5,97,0,0"/>  
                <Image x:Name="Image8" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="199.5,97,0,0"/>  
                <Image x:Name="Image9" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="261.5,97,0,0"/>  

                <Image x:Name="Image10" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="13.5,159,0,0"/>  
                <Image x:Name="Image11" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="75.5,159,0,0"/>  
                <Image x:Name="Image12" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="137.5,159,0,0"/>  
                <Image x:Name="Image13" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="199.5,159,0,0"/>  
                <Image x:Name="Image14" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="261.5,159,0,0"/>  

                <Image x:Name="Image15" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="13.5,221,0,0"/>  
                <Image x:Name="Image16" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="75.5,221,0,0"/>  
                <Image x:Name="Image17" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="137.5,221,0,0"/>  
                <Image x:Name="Image18" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="199.5,221,0,0"/>  
                <Image x:Name="Image19" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="261.5,221,0,0"/>  

                <Image x:Name="Image20" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="13.5,283,0,0"/>  
                <Image x:Name="Image21" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="75.5,283,0,0"/>  
                <Image x:Name="Image22" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="137.5,283,0,0"/>  
                <Image x:Name="Image23" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="199.5,283,0,0"/>  
                <Image x:Name="Image24" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="261.5,283,0,0"/>  

                <Image x:Name="Image25" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="13.5,345,0,0"/>  
                <Image x:Name="Image26" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="75.5,345,0,0"/>  
                <Image x:Name="Image27" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="137.5,345,0,0"/>  
                <Image x:Name="Image28" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="199.5,345,0,0"/>  
                <Image x:Name="Image29" HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="60" Margin="261.5,345,0,0"/>  
            </Grid>  
        </ItemsControl>  
</GroupBox>  

C# Codes

//"Images" folder is in Solution Explorer  
![102579-images.png][1]  
DirectoryInfo DirInfo = new DirectoryInfo(@"Images/");  
FileInfo[] FileInfo = DirInfo.GetFiles();  
object[] ImagesList = FileInfo;  
for (int i = 0; i < 30; i++)  
{  
//Name of Control + Number  
var img = FindName("Image" + i.ToString()) as Image;  
img.Source = (BitmapImage)ImagesList[i];  
}  

Thanks

XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
809 questions
0 comments No comments
{count} votes

Accepted answer
  1. DaisyTian-1203 11,621 Reputation points
    2021-06-07T02:52:35.47+00:00

    Failed reason 1: The number of your images is 7, you use ImagesList[i] which scope is 0~30, it is out of array size.
    Failed reason 2: It is not a good way to convert object[] ImagesList to BitmapImage like yours.

    I update your code like below:

     DirectoryInfo DirInfo = new DirectoryInfo(@"Images/");  
                FileInfo[] FileInfo = DirInfo.GetFiles();  
                Random rd = new Random();  
                for (int i = 0; i < 30; i++)  
                {  
                    int n = rd.Next(0, FileInfo.Count());  
                    var img = FindName("Image" + i.ToString()) as Image;  
                    img.Source = new BitmapImage(new Uri(FileInfo[n].FullName.ToString(), UriKind.RelativeOrAbsolute));  
                }  
    

    The result picture is:
    102698-capture.png

    Update
    Add a button to show/refresh all pictures without duplication, the cs code is:

    public void LoadImages()  
            {  
                Random rand = new Random();  
                DirectoryInfo DirInfo = new DirectoryInfo(@"Images/");  
                FileInfo[] FileInfo = DirInfo.GetFiles();  
      
                int num = FileInfo.Count();  
                List<int> lt = new List<int>();  
                int number;  
                for (int i = 0; i < num; i++)  
                {  
                    do  
                    {  
                        number = rand.Next(0, num);  
                    } while (lt.Contains(number));  
                    lt.Add(number);  
                }  
                for (int i = 0; i < num; i++)  
                {  
                    int x = lt[i];  
                    var img = FindName("Image" + i.ToString()) as Image;  
                    img.Source = new BitmapImage(new Uri(FileInfo[x].FullName.ToString(), UriKind.RelativeOrAbsolute));  
                }  
            }  
      
            private void Button_Click(object sender, RoutedEventArgs e)  
            {  
                LoadImages();  
            }  
    

    The updated result picture is:
    103618-3.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. رضا جافری 1,296 Reputation points
    2021-06-08T03:58:01.21+00:00

    To avoid duplicate images i added the following codes but it gives an error: 'The process cannot access the file because it is being used by another process.' line 12

    DirectoryInfo DirInfo = new DirectoryInfo(@"Images/");
    FileInfo[] FileInfo = DirInfo.GetFiles();
    Random random = new Random();
    for (byte i = 0; i < 30; i++)
    {
      byte r = (byte)random.Next(0, FileInfo.Count());
      var img = FindName("Image" + i.ToString()) as Image;
      img.Source = new BitmapImage(new Uri(FileInfo[r].FullName.ToString(), UriKind.RelativeOrAbsolute));
      //I want to remove the image from the FileInfo array after display it.
      GC.Collect();
      GC.WaitForPendingFinalizers();
      using (FileStream fs = System.IO.File.Create(FileInfo[r].FullName.ToString(), Int16.MaxValue, 
      FileOptions.DeleteOnClose))
      {
       FileInfo[r].Directory.Delete();
      }
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.