Windows Vista RC1

I have the RC1 build of Windows Vista running on an old-ish machine at work – the machine has 512 MB of RAM, which means that my Windows Experience Index is a measly 2.9. Given that, I was pleasantly surprised to find that the OS is quite zippy, and not to mention extremely fun to use! It’s very exciting to see how much the performance and polish are improving with every build. You can download RC1 from here.

Launching the Browser from a Hyperlink

One question that has been coming up frequently over the past few days has been how to launch the browser when the user clicks on a hyperlink. The answer is different for the browser and standalone cases:

Browser (XBAP or Loose XAML)

XBAPs and loose XAML support special named targets for Hyperlink; these are the same named targets that are supported by HTML:

  • _self: the browser should load the document in the same frame as the element that refers to this target
  • _parent: the browser should load the document into the immediate parent frame of the current frame. This value is equivalent to _self if the current frame has no parent.
  • _blank: the browser should load the document in a new, unnamed window
  • _top: the browser should load the document into the full, original window (thus canceling all other frames). This value is equivalent to _self if the current frame has no parent.

The following XAML illustrates using a special target:

<TextBlock>
   <Hyperlink NavigateUri="http://microsoft.com" TargetName="_top">
      Navigate the top-level window to Microsoft.com
   </Hyperlink>
</TextBlock>

If you specify a target that does not exist, a new browser window will be created and the navigation will occur in that window. If you specify a target that already exists, the existing browser window will be used.

This functionality all relies on the named browser targeting feature that already exists in Internet Explorer. Note that the WPF navigation framework also supports named targets, so if you have a Frame in your Window named “_self,” “_top,” etc., those Frames will be searched first before delegating to the browser. This means that the hyperlink targeting logic will start by looking for an Avalon Frame inside the application with the specified name. If it does not find it, and the application is hosted in the browser, then it will call the browser’s navigate function with the specified target name.

I have a sample HTML page that hosts loose XAML in an iframe and demonstrates each of the special hyperlink targets. You can try it out here, and download both pages from here.

Standalone

Unfortunately WPF v1 does not have this convenient feature in the standalone case as well, since we can’t call into the browser in this case. For standalone scenarios, the simplest way to accomplish this task is to handle Hyperlink’s RequestNavigate event, and launch the default browser in your event handler.

The following XAML creates the Hyperlink and attaches an event handler:

<TextBlock>
   <Hyperlink RequestNavigate="HandleRequestNavigate" Name="hl" 
      NavigateUri="http://microsoft.com">
      Open Microsoft.com in the default browser
   </Hyperlink>
</TextBlock>

And the following code implements the event handler:

void HandleRequestNavigate(object sender, RoutedEventArgs e)
{
   string navigateUri = hl.NavigateUri.ToString();
   // if the URI somehow came from an untrusted source, make sure to
   // validate it before calling Process.Start(), e.g. check to see
   // the scheme is HTTP, etc.
   Process.Start(new ProcessStartInfo(navigateUri));
   e.Handled = true;
}

You can download the source for this sample here.

Creating a File Upload Control that Works in the Sandbox

In HTML, it is easy to add file upload capabilities to your application using the INPUT element with type=”file”:

<input type="file" />

This renders a text box and a button, and when a user clicks on the button she is confronted with a file open dialog. She selects a file, and the text box gets populated with file name:

The input element is usually used inside of a form, and the contents of the file are sent to the form processing agent when the form is submitted.

WPF does not provide a file upload control out of the box, but it is very easy to construct your own using a TextBox, a Button, and Microsoft.Win32.OpenFileDialog. I have created a simple version of this control by deriving from UserControl. My UserControl has one public property, called File, which is of type Stream, and an event, called FileSelected, which is raised when the user chooses a new file using the OpenFileDialog.

The main logic for this control lives in the Click event handler for the Button:

        void SelectFile(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            bool? dialogResult = ofd.ShowDialog();

            if (dialogResult == true)
            {
                TBFileName.Text = ofd.SafeFileName;
                file = ofd.OpenFile();

                // raise the FileSelected event:
                OnFileSelected(EventArgs.Empty);
            }
        }

In order to make this work inside the sandbox for an Internet Zone XBAP, I need to populate the TextBox using the SafeFileName property on OpenFileDialog, rather than using the FileName property. FileName will provide the full path to the file, and hence is not safe to use in partial trust (you will get a SecurityException if you try to use it from an Internet Zone XBAP). SafeFileName gives you a sanitized file name – simply the name of the file, without disclosing the path. This may be used safely by a partial trust application.

If you have the July CTP installed, you can try out a little test XBAP that uses this control here. You can download source for the control and the test app here.

Which Build is Right for You?

There seems to be some confusion about the new July CTP, and how to use it without a new build of Orcas (in fact, Orcas is just the dev environment, and you should be able to use the July framework with the June build of Orcas). In order to help clarify which build is right for you, Tom Archer has posted a thorough discussion of the differences between the different builds and how to get the right combination of tools (thanks Ashish for the tip).