#1,111 – Referencing Content Files from XAML

You can choose whether to embed an image resource in your application’s executable file or to have the file copied to the output directory.

Whether the image resource is embedded in the executable or copied to the output directory, you can reference the image from XAML elements in the same way, by just using the name of the image (assuming that the image is located in the root of the solution).

Below, the “Chico” image has its Build Action set to Resource (embed in executable).  The “Groucho” image has its Build Action set to Content (read from output directory).

1111-001   1111-002

In XAML, we refer to the images in the same way.

    <StackPanel Orientation="Horizontal">
        <Image Source="Groucho.jpg" Height="100"
               Margin="10"/>
        <Image Source="Chico.jpg" Height="100"
               Margin="10"/>
    </StackPanel>

When we run the application, both images are loaded successfully.

1111-003

#1,110 – Using a Resource as a Content File

When your application needs to use a resource (e.g. an image), it can embed the resource in the executable for the application.  You can then access the resource at run time using a Uri like the one shown below.

BitmapImage bmi = new BitmapImage(new Uri("pack://application:,,,/Ted.jpg"));

You can also include an image in your project and then cause the image to be placed in an output directory along with the executable, but not embedded within it.  You do this by setting its Build Action to Content and by setting the Copy to Output Directory property.

1110-001

In this case, after building the project, the .jpg file is copied to the output directory.

1110-002

At run time, you can use exactly the same Uri to access the file, although it is external to the application, rather than embedded.

#1,109 – Accessing a Resource in a Different Assembly

You can use the following URI, in code, to access a resource embedded into the executing assembly.

                    BitmapImage bmi = new BitmapImage(new Uri("pack://application:,,,/Images/Ted.jpg"));

If you want to access a resource in a different assembly, you use the Uri syntax shown below, adding the assembly name and the word “component”.

                    BitmapImage bmi = new BitmapImage(new Uri("pack://application:,,,/MyPictures;component/Ted.jpg"));

This assumes that the image Ted.jpg is included in an assembly named MyPictures (e.g. in MyPictures.dll).  It also assumes that the Build Action for the image is set to Resource and that this assembly is in the same directory as the executing assembly.  If you want the resource assembly to end up in the same output directory as the main assembly, you’ll want to add a reference to it from the main assembly.

#1,108 – Use Reflector to Get List of Resources

You can use the third party .NET Reflector tool to get more information on the contents of a .NET (e.g. WPF) assembly.  .NET Reflector is available from Red Gate Software.  Included in the list of information displayed in Reflector is a full list of all resources embedded in the assembly.

To start with, you open the assembly within Reflector.  You do this by browsing to the .exe file containing the assembly.

1108-001

 

Once you open the assembly, you can look at the contents, including any resources embedded within the assembly.  In the example below, we find the image ted.jpg in the images sub-folder.

1108-002

 

 

 

#1,107 – Accessing an Embedded Resource Using a Uri

You can embed images into your WPF application as resources and then access them from code at run-time.

To embed an image as a resource, add it to your project and set its Build Action to Resource.

1107-001

You can now access this image at run-time using a Uri.  The URI for a simple resource just includes the path to the image.

In the example below, we use a URI to locate an image in the Images folder.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                BitmapImage bmi = new BitmapImage(new Uri("pack://application:,,,/Images/Ted.jpg"));

                MessageBox.Show(string.Format("Image is {0}x{1} pixels", bmi.Width, bmi.Height));
            }
            catch (Exception xx)
            {
                MessageBox.Show(xx.ToString());
            }
        }

The pack://application portion of the Uri indicates that the resource is compiled into the current assembly.  The portion of the Uri after the third comma describes the path to the image.

1107-002

#1,106 – Creating a Single Instance Application

By default, when you build an application, the user can run multiple copies of the application.  Each one runs independently, managing its own window(s).  There are times, however, when you might want to enforce that no more than one instance of your application runs at a time.  You can do this using the Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase class.

You start by adding a reference to Microsoft.VisualBasic.dll.

1106-01

1106-02

You next create a class that derives from WindowsFormsApplicationBase and does the following:

  • Sets IsSingleInstance property to true (in constructor)
  • Overrides OnStartup method and creates an instance of your main WPF application class
    • (For first startup)
  • Overrides OnStartupNextInstance and reactivates the main window
    • (For subsequent startups)
    public class MyApplicationBase : WindowsFormsApplicationBase
    {
        private App myApp;

        public MyApplicationBase()
        {
            this.IsSingleInstance = true;
        }

        // Called when user starts the first instance of the app
        protected override bool OnStartup(StartupEventArgs eventArgs)
        {
            myApp = new App();
            myApp.InitializeComponent();

            // Run application (this call blocks)
            myApp.Run();

            return false;
        }

        // Called when user tries starting another instance
        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
        {
            base.OnStartupNextInstance(eventArgs);

            // App already running, so just bring window to front
            if (myApp.MainWindow.WindowState == System.Windows.WindowState.Minimized)
                myApp.MainWindow.WindowState = System.Windows.WindowState.Normal;
            myApp.MainWindow.Activate();
        }
    }

Next, you need to create a new Main method, where you’ll instantiate the new class.

    public class Startup
    {
        [STAThread]
        public static void Main(string[] args)
        {
            MyApplicationBase appBase = new MyApplicationBase();
            appBase.Run(args);
        }
    }

Finally, you’ll configure the project properties so that this new Startup.Main method is the startup object for your application.
1106-03

#1,104 – How the Splash Screen Works

You can configure a splash screen in a WPF application by adding an image to the solution and setting its build action to SplashScreen.  The image will appear while the application is loading and then disappear as soon as the main window appears.

You can see how the splash screen works by looking at the code generated at build time for your main application class.  This will be in a file that looks something like App.g.cs.

To open the file, enable the Show All Files option and then look for App.g.cs under the obj directory.

1104-001

In the Main method, a SplashScreen instance is created and the name of the image is passed to its constructor.  It’s Show method is called and then the normal Application initialization is done. The Show method accepts a boolean indicating that the splash screen should be hidden once the main window is shown.

1104-002

 

Follow

Get every new post delivered to your Inbox.

Join 374 other followers