Tuesday, March 27, 2007

WPF/E - GeoPhoto - A User Control With Fun in Mind

UPDATE - 05.06.2007 - The content of this post is no longer valid with the 1.0 beta release of Silverlight.

Greetings,

One of my hobbies is Geocaching. Because of this, I decided to keep a blog regarding my caching adventures. I wanted this blog to be very heavily focused on pictures and location to help readers connect with the locations. This seemed like a perfect opportunity to create a reusable component that would allow me to load location specific images. The control displays images and if the "swap" icon is selected, a Virtual Earth map of the location of the photo is displayed. Hence the birth of GeoPhoto.

On the WPF/E side of the ball, this component is interesting because it demonstrates some very powerful, and valuable, techniques including:
  • Displaying HTML content ON TOP OF WPF/E content. I have not seen this implemented elsewhere. Everything else I have seen involves displaying WPF/E content on top of HTML content
  • Exposing ASP.NET user control properties to client (JavaScript) code
  • A fairly smooth slider "control".
  • Converting data from an XML file into JavaScript objects that are used throughout the application.
  • Creating a TRUE User Control in that you can actually use it several times on the same page.

This control reads the image: source, latitude, and longitude values from an xml file. The xml file location is actually exposed as a property of the user control. This control allows you to do the following:
  • Define the source of a picture and it's latitude, longitude
  • Define a latitude and longitude for a group of pictures
  • Define picture groups for multiple locations.

Please bear in mind, this control can be expanded upon to be more robust. This was primarily designed to be used for a specific case, and then I expanded it to be a bit more reusable, then I decided to share it through my blog. I hope you find it useful. There are several items that can definately be improved upon. One item is I would like to utilize the Downloader object more. Another one of these items is the fact that the control currently doesn't work in Firefox. I believe there is a bug in the Feb CTP that does not allow the SourceElement of a WPF/E control to be accessed when attempted through Firefox. I have posted a question on the forum regarding this. I hope to find some time to remedy this, and if so, I will definately make a post about it (so make sure you use the RSS subscription :)).

Over the next couple of weeks, leading up to MIX '07, I intend to write some more detailed posts regarding some of the points listed above. These posts will be based on the GeoPhoto control, and now is as good as time as any to make this control available. I look forward to your comments.

Project Information
    Source Code: here
    Requirements: WPF/E February 2007 CTP

Monday, March 19, 2007

WPF/E - How to get the id of the hosting WPF/E control

UPDATE - 05.06.2007 - The content of this post is no longer valid with the 1.0 beta release of Silverlight.

The February 2007 CTP of the WPF/E SDK provides the "GetHost" method which enables ANY UIElement to get the hosting WPF/E control of the object. Unfortunately, there is not a property or method that exposes the ID of the WPF/E control (as of the Feb 2007 CTP). In the event you are attempting to create a reusable component, you will probably want the ID of the control so that you can reuse all of the JavaScript you have laboriously authored :)

After reviewing the items available through the WPF/E control API, I settled on an approach that seems usable. I used the SourceElement property when I declared my WPF/E control. Click the button below to display the WPF/E control information.

The key item to notice is that these are two seperate instances of the same xaml file. The source code for this implementation is available at the end of this post.

I simply declared the WPF/E control in the HTML as follows:

<div id="wpfeControl1Host">
  <script type="text/javascript">
    new agHost
    (
      "wpfeControl1Host", // hostElementID (HTML element to put WPF/E control into)
      "wpfeControl1", // ID of the WPF/E ActiveX control we create
      "400", // Width
      "400", // Height
      "white", // Background color
      "wpfeControl1", // SourceElement (name of script tag containing xaml)
      "plugin.xaml", // Source file
      "false", // IsWindowless
      "30", // MaxFrameRate
      null // OnError handler
    );
  </script>
</div>

Notice the relationship between the "ID of the WPF/E ActiveX control", the "SourceElement" property, and the
id of the containing "Div" element. The relationships are as follows:
  • The "SourceElement" is set to the ID of the WPF/E ActiveXControl
  • The "hostElementID" is set to the "SourceElement" + a unique number to identify the instance
  • The "id" of the "div" tag is set to the "hostElementID". I point this out simply because if you are using this as a checklist you can just go down the list.
This naming structure is implemented to give us the flexibility of obtaining BOTH the id of the WPF/E ActiveX control and the id of the hosting element from the JavaScript. Now that we have setup the relationships we can obtain the various
IDs.

Using the "WPF/E JavaScript Application" Visual Studio 2005 Template asa basis, simply replace the "handleMouseUp" function
with the following:

function handleMouseUp(sender, eventArgs)
{
  var gradientStop1 = sender.findName("gradientStop1");
  var gradientStop2 = sender.findName("gradientStop2");
  gradientStop1.offset = 1;
  gradientStop2.offset = .403;

  // Obtain a reference to the WPF/E control
  var wpfeControl = sender.GetHost();
  var displayString = new String();

  // Display the ID of the ActiveX (WPF/E) control
  displayString += "The ID of the ActiveXControl is " + wpfeControl.SourceElement + "\n\n";

  // Display the ID of the HTML element that is hosting the control
  var hostingElementID = wpfeControl.SourceElement + "Host";
  displayString += "The ID of the Hosting HTML element is " +   hostingElementID + "\n\n";

  // Display the HTML of the "control" for the sake of proof
  if (document.all)
  {
    var hostingElement = document.getElementById(hostingElementID);
    displayString += "The HTML of the \"control\"\n";
    displayString += "-------------------------------------------";
    displayString += hostingElement.outerHTML;
  }
  alert(displayString);
}

I settled upon this approach primarily because it worked :). However, I was originally led down the path because of the comment in the HTML file that states "// SourceElement (name of script tag containing xaml)". I think the confusion is because of there seems to be a discrepency between this comment and the contents of the information within the SDK for the "SourceElement" property. I look forward to your comments.

Project Information
    Source Code: here
    Requirements: WPF/E February 2007 CTP

Saturday, March 17, 2007

Misc - New Layout

I came to the decision that I didn't like the appearance of my blog. Thus, I decided to move forward with a redesign. In selecting a design, I wanted to make the following improvements that I felt were lacking from the previous version.
  • Improved Readibility - The font is now larger, more distinct, and clearer
  • Focus on Content - WPF and WPF/E can more easily standout as the focus of a blog post now
  • Community Involement - Links are now available to those sites that are directly related to this blog's content. Including blogs that link to this site and other resources. In addition, I registered for feedburner to help guauge reader interest level. So if you are already a subscriber, I would appreciate it if you update your rss feed url through the "Subscription" link on the right side of the page.
  • Flexibility - I would like to incrementally include WPF/E content into this blog.
  • Navigation - Personally, I ran into difficulties finding content on my own blog. The use of the hierarchy control has simplified this process.


I hope you like the new design. I hope to have some new .NET related content posted soon.

Sunday, March 11, 2007

WPF/E - MIX Bling

UPDATE - 05.05.2007: The content of this post is no longer valid with the 1.0 beta release of Silverlight. The updated post and source code can be found here.

Hola! I'm getting pumped for Mix and I haven't seen a lot of bling out on the web yet. So I decided to add my 2 cents to the mix (no pun intended).

I've posted the code and this can be easily extended to implement some functionality with the buttons to make this a full blown media player. In fact, this component was created to host a 320x240 video. Originally, I wanted to display this component horizontally instead of vertically, which is why the borders are a little messed up. The source code available for download is actually the horizontal version so the borders of the device look better. Enjoy!

Project Information
    Source Code: here
    Requirements: WPF/E February 2007 CTP

Wednesday, March 07, 2007

WPF/E - How to Create a Media Player

[Spoiler Alert] - This content will be presented at the Kentucky .NET User Group on March 8th, 2007 [/Spoiler Alert]

During the March 8th, 2007 Kentucky .NET User Group meeting I will be presenting an overview of WPF/E. In addition to the overview, I decided it would be helpful to provide a walkthrough of creating a media player to familiarize individuals with the platform.

While I was practicing presenting, I decided to record my presentation and try my hand at my first webcast. If you decide to watch the webcast, I would recommend waiting for the video to be 10% downloaded before clicking the "play" button. I apologize for the inconveniance, however, my presentation has a time limit and I was trying to focus on a lot of the core features of WPF/E. I will try to blog on an intelligent download/playback handler sometime in the near future. Please let me know if you have any questions.

Project Information
    Presentation: here
    Duration: 44:23
    Source Code: here
    Requirements: WPF/E February 2007 CTP

Saturday, March 03, 2007

WPF/E - How to dynamically load a XAML File

UPDATE - 05.05.2007: This content of this post is no longer valid with the 1.0 beta release of Silverlight. The updated post and source code can be found here.

Recently on the WPF/E forum someone was asking about how to dynamically load a XAML file. This post will explain how to accomplish this.

One of the great features of WPF/E is the fact that it is consistent with an established web architecture. At a high-level overview, within a webpage, a WPF/E component is hosted within an HTML element and you can use JavaScript to interact with the XAML content.

When working with XAML within the web architecture, it is important to remember both the Document Object Model (DOM) and the WPF/E Object Model.

Now let's get into the details of how to solve the problem of dynamically loading a XAML file. This really cool part is that we can do this in three easy steps.

  1. Reference the WPF/E control via the Document Object Model (DOM).
    var wpfeControl = document.getElementById("wpfeControlID");
     
  2. Use the "Source" property of the WPF/E control to specify a XAML file.
    wpfeControl.Source = "pathToXamlFile.xaml";
     
  3. Reload the content of the WPF/E control with the contents of XAML file referenced by the "Source" property.
    wpfeControl.Reload();
For larger xaml files, it's generally recommended to use the Downloader object to enhance the user's experience. Here is a sample that loads a different .xaml file based upon the selected item. In addition the code for this sample is posted below. Thanks alot!

Project Information
Source Code: here
Requirements: WPF/E February 2007 CTP