Simple winform that randomizes images in a picturebox
private void initializeImages()
    {
        string appRoot = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
        files = System.IO.Directory.GetFiles(appRoot + @"\Resources");
        files2 = System.IO.Directory.GetFiles(appRoot + @"\Resources");
        files3 = System.IO.Directory.GetFiles(appRoot + @"\Resources");
        files4 = System.IO.Directory.GetFiles(appRoot + @"\Resources");
        files = files.OrderBy(x =&gt; rnd.Next()).ToArray();
        files2 = files.OrderBy(x =&gt; rnd.Next()).ToArray();
        files3 = files.OrderBy(x =&gt; rnd.Next()).ToArray();
        files4 = files.OrderBy(x =&gt; rnd.Next()).ToArray();
    }



Here you load the same file names into four different arrays of strings. This is very memory inefficient and unnecessary. Instead only load them once into a single array and shuffle that when you want to change the images in the picture boxes.

In general: when you feel the need to add indices to the names of a set of variables like you do, you should reconsider your design - and you'll probably realize that an array or list or other kind of collection is the solution.




Random rnd = new Random();



In general: avoid abbreviated names of properties, fields, methods, object/classes etc. Provide descriptive names and let intellisense in the IDE do the work for you. Here random or randomGenerator would be descriptive names.




private void button1_Click(object sender, EventArgs e)
    {
        initializeImages();
        nextImage();
    }



Here you repeatedly reload the image file names. This makes sense if the number of images in the location changes - but you look in a sub folder to the installation folder which indicates that they are rather constant, so no need to do it other than when the form loads.



Below I've tried to refactor your code while implementing the above suggestions:

private string[] imageFileNames;
Random random = new Random();

public Menu()
{
  InitializeComponent();

  InitializeImages();
}

private void InitializeImages()
{
  imageFileNames = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Resources"));
}

private void ShuffleImages()
{
  Array.Sort(imageFileNames, (a, b) =&gt; random.Next(0, 3) - 1);
}

private void SetImages()
{
  var picturBoxes = new[] { pictureBox1, pictureBox2, pictureBox3, pictureBox4 };

  for (int i = 0; i &lt; picturBoxes.Length; i++)
  {
    picturBoxes[i].ImageLocation = imageFileNames[i % imageFileNames.Length];
  }
}

private void button1_Click(object sender, EventArgs e)
{
  ShuffleImages();
  SetImages();
}




If the number of images is limited you can consider to load them all once into an list of Image objects and then shuffle these instead of the file names.

private void InitializeImages()
{
  images = Directory
    .GetFiles(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Resources"))
    .Select(fn =&gt; Image.FromFile(fn)).ToArray();
}