|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
|
|
PhillyXAML.org > Blog > Categories
|
5/6/2010
I did something I would like to share and figure this is the best way to do it. I took an email regarding the Silverlight 4 Training Kit and used it to download the local version of the kit. I found out quickly that the links to the videos in the kit still use web-based targets for the video file, so basically the kit wraps everything into one bundle EXCEPT for the actual videos, which are served out by Channel 9.
So here is what I did… I took the kit and wrote a small utility that pulled all the video.xml files out of the kit and parsed each one to get the valid URL for the relative video file. I then took that data and dynamically constructed a Windows Media Player WPL Playlist file which is simply a continuously playing list of the video files in the correct order. This way I can start at the beginning and watch it continuously without having to manually navigate to each file as I need it.
Anyway, here is the playlist file, for anyone interested. I think this is something people will find highly valuable as I did. The descriptive content in the kit is nice and all, but a little tedious for those who just want to work their way through it. Just thought I would share. This way people can have one item (the playlist) to track, and additionally, the playlist is very easy to distribute and launch by either dropping it in the playlist folder ([%userprofile%]\music\playlists) to be picked up by Windows Media Player or simply double clicked to play it. Also works on Windows Media Player 9 and above, which about 99% of people have by now so it is virtually universal.
Content of the playlist file is as follows: <?wpl version="1.0"?>
<smil>
<head>
<meta name="Generator" content="Microsoft Windows Media Player -- 12.0.7600.16415"/>
<meta name="ItemCount" content="2"/>
<author/>
<title>Silverlight 4 Training Kit</title>
</head>
<body>
<seq>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule1-SL4LOB_01_01_Introduction/Silverlight4-SL4BusinessModule1-SL4LOB_01_01_Introduction_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule2-SL4LOB_02_01_RIAServices/Silverlight4-SL4BusinessModule2-SL4LOB_02_01_RIAServices_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule2-SL4LOB_02_02_EditingEntities/Silverlight4-SL4BusinessModule2-SL4LOB_02_02_EditingEntities_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule2-SL4LOB_02_03_ShowingEvents/Silverlight4-SL4BusinessModule2-SL4LOB_02_03_ShowingEvents_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule3-SL4LOB_03_01_Authentication/Silverlight4-SL4BusinessModule3-SL4LOB_03_01_Authentication_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule3-SL4LOB_03_02_MVVM/Silverlight4-SL4BusinessModule3-SL4LOB_03_02_MVVM_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule3-SL4LOB_03_03_Validation/Silverlight4-SL4BusinessModule3-SL4LOB_03_03_Validation_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule3-SL4LOB_03_04_ImplicitStyles/Silverlight4-SL4BusinessModule3-SL4LOB_03_04_ImplicitStyles_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule3-SL4LOB_03_05_RichTextBox/Silverlight4-SL4BusinessModule3-SL4LOB_03_05_RichTextBox_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule4-SL4LOB_04_01_Webcam/Silverlight4-SL4BusinessModule4-SL4LOB_04_01_Webcam_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule4-SL4LOB_04_02_Drop/Silverlight4-SL4BusinessModule4-SL4LOB_04_02_Drop_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule5-SL4LOB_05_01_Grouping/Silverlight4-SL4BusinessModule5-SL4LOB_05_01_Grouping_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule5-SL4LOB_05_02_FluidUI/Silverlight4-SL4BusinessModule5-SL4LOB_05_02_FluidUI_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule5-SL4LOB_05_03_RightMouseClick/Silverlight4-SL4BusinessModule5-SL4LOB_05_03_RightMouseClick_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule6-SL4LOB_06_01_Printing/Silverlight4-SL4BusinessModule6-SL4LOB_06_01_Printing_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule6-SL4LOB_06_02_MultipagePrinting/Silverlight4-SL4BusinessModule6-SL4LOB_06_02_MultipagePrinting_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule7-SL4LOB_07_01_OOB/Silverlight4-SL4BusinessModule7-SL4LOB_07_01_OOB_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule7-SL4LOB_07_02_Toasts/Silverlight4-SL4BusinessModule7-SL4LOB_07_02_Toasts_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule7-SL4LOB_07_03_WindowPlacement/Silverlight4-SL4BusinessModule7-SL4LOB_07_03_WindowPlacement_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule7-SL4LOB_07_04_ElevatedTrust/Silverlight4-SL4BusinessModule7-SL4LOB_07_04_ElevatedTrust_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule8-SL4LOB_08_01_CustomChrome/Silverlight4-SL4BusinessModule8-SL4LOB_08_01_CustomChrome_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule8-SL4LOB_08_02_WindowClosingEvent/Silverlight4-SL4BusinessModule8-SL4LOB_08_02_WindowClosingEvent_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule8-SL4LOB_08_03_OOBSilentInstall/Silverlight4-SL4BusinessModule8-SL4LOB_08_03_OOBSilentInstall_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule8-SL4LOB_08_04_XapSigning/Silverlight4-SL4BusinessModule8-SL4LOB_08_04_XapSigning_kit.wmv"/>
<media src="http://ecn.channel9.msdn.com/o9/learn/videos/Silverlight4-SL4BusinessModule8-SL4LOB_08_05_MEF/Silverlight4-SL4BusinessModule8-SL4LOB_08_05_MEF_kit.wmv"/>
</seq>
</body>
</smil>
4/23/2010
This post is the first video post on the site, and covers how to build a Silverlight Media Player that you can use in any web page whether it be static HTML, ASP, ASP.NET, SharePoint, PHP, whatever. More specifically, it shows how I built the media player you will use if you choose to watch this video tutorial!
My particular implementation uses SharePoint (MOSS 2007), where I am hosting the script file, master page, CSS stylesheet, and the player .xap file file as well as all of my WMV media files. After all, is this not what SharePoint was designed for? I do however use a third-party Silverlight media player control, provided by ComponentOne, but in a subsequent post I will describe how this can be easily modified to use the Smooth Streaming Media Player from the Silverlight Media Framework. This way, this can be an entirely free solution to create for your own websites.
We are really just creating a wrapper for an existing media player control. We are NOT writing any kind of playback functionality, full-screen capabilities, volume control, or even providing any kind of UI, short of our one single third-party control that occupies our entire default grid. After watching the video or downloading the code, it should be pretty easy to modify this shell to fit your particular player needs.
So, how does it work? Basically, we are going to use jQuery and some very simple markup to easily add media to blog posts, articles, whatever, wherever, whenever. Our script takes 2 attributes of a div tag we add to our page as a placeholder, and dynamically generates the correct object and param tags for displaying a single Silverlight player file, initialized with whatever Title and WMV file URL we pass it. It then uses jQuery to insert some templated markup right into the DOM as the content of the placeholder div we added.
One of the limitations I encountered with my personal solution, was that SharePoint strips out object and param tags from content fields that use the HTML Editor... so no matter what I did, I could not add my player to a page as markup in a content field. From a Content Editor Web Part, I could add the correct tags, but not as content in an HTML field.
With this solution, I can easily add a div tag with valid attributes that wont be stripped out, and when the page loads it takes that info in $(document).ready() and inserts instances of the player pointing to the correct Video URL wherever a div with a certain class is found! Minimal markup, powerful reuse!
In my implementation, the script is embedded in my master page and works on all pages in the SharePoint Site that use that master page. Because its only javascript, jQuery, Silverlight and CSS, it will work anywhere where we have the ability to execute the javascript calls!
Now, I vaguely remember someone mentioning a video in here somewhere?
4/20/2010The third installment of this series will cover creating an overloaded method that will allow us to fade a control to a specific opacity, as well as give us the ability to fade in or out. A scenario for this might be to fade a window out, open a dialog, and after the dialog call, fade the window back in.
This is a scenario we see on the Web all the time, and more recently in client applications to indicate synchronous, blocking processing where the application needs to "pause" its UI layer, indicating it is disabled, and more importantly creating focal emphasis on the dialog element. We visit a page, click Login, the window disables and fades, a new window opens, we log in, the login window closes, and the parent window fades back in and its back to business as usual.
Another use for this method would be to facilitate some simple animations of UI elements that are displayed dynamically based on application context. An example might be a client application that has a datagrid that appears or disappears depending on whether or not there is data. While still allowing the grid to occupy the same screenspace whether it is hidden or not, we can provide some enhanced interactivity by fading that grid in or out when there is data instead of instantaneously popping it on or off the screen. This creates a more dynamic feel to the application and really works to richen our user experience.
We will program the option to fade in or out with several overrides, comprised of combinations of the items below:
- Fade to a specific opacity
- Fade over a fixed duration of time
- Fade based on direction (In, Out)
The first thing we need to do is add a new item to our library. Create an empty code file named Enums.cs and add the following code. We do not need any using statements since this file will only contain an enumerator used for determining fade directionality. namespace PX.Samples.FrameworkElementExtender
{
public enum Fade { In, Out };
}
With our enumerator in place, we add the following method overrides to FrameworkElementExtender.cs. The comments for each method indicate the specific combination of the above features the method provides. Also note the string constant fadeDuration, which is used as a default for some of the overrides. #region FadeInOut Extension Method
private const string fadeDuration = "0:0:0.5";
/// <summary>
/// Fades the FrameworkElement in or out over a specified duration
/// </summary>
/// <param name="elUI">The FrameworkElement being extended</param>
/// <param name="FadeDirection">Direction to fade, In or Out</param>
/// <param name="Duration">Valid TimeSpan string in the format
/// d.h:m:s.sss where h:m:s is required</param>
public static void FadeInOut(this UIElement elUI, Fade FadeDirection, string Duration)
{
TimeSpan duration;
if (!TimeSpan.TryParse(Duration, out duration))
{
throw new Exception(string.Format("{0} is not a valid value for Duration", Duration));
}
if (FadeDirection == Fade.Out)
{
FadeInOut(elUI, .03, Duration);
}
else
{
FadeInOut(elUI, 1, Duration);
}
}
/// <summary>
/// Fades the FrameworkElement in or out over the default duration
/// </summary>
/// <param name="elUI">The FrameworkElement being extended</param>
/// <param name="FadeDirection">Direction to fade, In or Out</param>
public static void FadeInOut(this UIElement elUI, Fade FadeDirection)
{
FadeInOut(elUI, FadeDirection, fadeDuration);
}
/// <summary>
/// Fades the FrameworkElement to a specific opacity over a specified duration
/// </summary>
/// <param name="elUI">The FrameworkElement being extended</param>
/// <param name="Opacity">The normalized opacity value between 0.0 and 1.0</param>
/// <param name="Duration">Valid TimeSpan string in the format
/// d.h:m:s.sss where h:m:s is required</param>
public static void FadeInOut(this UIElement elUI, double Opacity, string Duration)
{
TimeSpan duration;
if (!TimeSpan.TryParse(Duration, out duration))
{
throw new Exception(string.Format("{0} is not a valid value for Duration", Duration));
}
DoubleAnimation da;
da = new DoubleAnimation(Opacity, duration);
elUI.BeginAnimation(Window.OpacityProperty, da);
}
/// <summary>
/// Fades the FrameworkElement to a specific opacity over the default duration
/// </summary>
/// <param name="elUI">The FrameworkElement being extended</param>
/// <param name="Opacity">The normalized opacity value between 0.0 and 1.0</param>
public static void FadeInOut(this UIElement elUI, double Opacity)
{
FadeInOut(elUI, Opacity, fadeDuration);
}
#endregion
Worth noting is the usage of the Fade enumerator to provide our logic switch for fading in or out. Additionally, the default fade out value is to an opacity of .03 or 3%. This provides a nice barely visible ghost of our control executing the method. This would the object elUI in the above code.
Lets take a look at the one override that really does all of the work, the override that takes a specific opacity and a specific duration, which is third in our code above. This override creates a DoubleAnimation object, and sets its To value and Duration using the respective constructor overload. We are then calling the BeginAnimation invoker on the extended element, passing in the DependencyProperty we wish to animate (UIElement.OpacityProperty) and the AnimationTimeline object that defines the animation (our DoubleAnimation object).
Also worth noting is that the additional method overrides are really just recursive versions of one another, using the fadeDuration string constant as a default when omitted. This combination of overrides covers all possible combinations of usage, which we will take a look at in just a moment.
First off, lets fix those ugly red errors in our code, by adding a using statement for System.Windows.Media.Animation so we can get to the DoubleAnimation object. Lets build to make sure we have made it this far without any errors. Build Succeeded! My two favorite words!
Now that we have a working library, lets modify our test harness application to use it. First open winMain.xaml in either Visual Studio or Expression Blend and double-click the top button to add an event handler. If you have been following along, the handler should be named btnSample_Click.
We are going to use the rectangle in the middle of our screen to test the different overrides. We are going to create a simple counter based loop so that each time we click the button we can step through the method calls and increment our counter. Add the counter variable indicated below as well. private int counter = 0;
private void btnSample_Click(object sender, RoutedEventArgs e)
{
switch (counter)
{
case 0:
counter++;
rectSample.FadeInOut(Fade.Out, "0:0:5");
break;
case 1:
counter++;
rectSample.FadeInOut(Fade.In, "0:0:2.5");
break;
case 2:
counter++;
rectSample.FadeInOut(Fade.Out);
break;
case 3:
counter++;
rectSample.FadeInOut(Fade.In);
break;
case 4:
counter++;
rectSample.FadeInOut(.5, "0:0:5");
break;
case 5:
counter++;
rectSample.FadeInOut(1, "0:0:5");
break;
case 6:
counter++;
rectSample.FadeInOut(.25);
break;
case 7:
counter = 0;//Reset our counter
rectSample.FadeInOut(1);
break;
default:
throw new Exception("This should never happen");
}
}
Now lets run our application by hitting F5 or Ctrl-F5. Now each time we click the button labeled Test Button 1 we will see each call as we click. We do not have any type of animation flow control in place in this simple sample so be sure to let the animations finish completely to avoid any unintended effect. Pay attention to which calls are being made in terms of fade direction and duration. 4/15/2010
The Silverlight 4 RTW is here and available at http://www.silverlight.net. Make sure to grab the Silverlight 4 Tools for Visual Studio 2010, The Silverlight 4 Toolkit and Expression Blend 4 RC while youre there to experience the entire development experience. The RTM version of Blend will be released in the upcoming months, but for now the RC works quite well and is pretty stable. More to come as it is available. Just got all the bits installed and am ready to play. 3/4/2010
So I've read about it (and was therefore lucky enough to quickly identify the issue) and knew how to fix it when it happened, but hadn't actually seen it applicable to an application yet.
So here it is. I have a Silverlight application that makes up a component in a web page. Probably saying "Wow"... So far no surprise. The main web application however, which is SharePoint (SL is hosted in a web part), uses jQuery and jQuery UI to display custom help in a modal dialog. When that modal dialog is displayed, the Silverlight plugin instance conceals some of the HTML output on the screen, ie the modal dialog, regardless of Z-Order, and furthermore is not dimmed/disabled as part of the modal dialog being shown.
The image below demonstrates the issue. In this image, and the one that follows, the area designated by the green boundary is the Silverlight application. The area designated in purple is the jQuery modal dialog that is being concealed.
Its also worth noting that the Silverlight application itself remains fully interactive while the "modal" dialog is being shown. This is because the Silverlight application is always set to take highest Z-Order by default, rendering after the HTML has already been rendered to the page, in a sense floating the plugin instance above the page.
I have read and verified that this issue will apply to all HTML-based controls on a page. The majority of issues reported seem to be around dropdowns disappearing behind Silverlight controls, which have their own designated real estate on the page, normally hiding the issue. Not ideally what we want in these situations.
Luckily, the fix is very simple. When we initialize our Silverlight control, we need to set the Windowless attribute equal to true. This will cause the Silverlight application to be rendered in the correct Z-Order with a slight, but virtually unnoticeable performance hit. This will allow our dialog to be rendered after, and therefore on top of our Silverlight control. Additionally, since the control is already rendered to the page, and not floating above the page, so to speak, the browser can handle disabling access to the application by disabling the page, greying it out, etc.
Since the recommended method for adding Silverlight to a page is to use an <object> tag with nested <param> tags, that is what we will cover here. To add our Silverlight instance, we probably have something like this markup generated by Visual Studio by default (with the exception of the initParams parameter shown for example):
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/someXapFile.xap"/> <param name="onError" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="3.0.40624.0" /> <param name="autoUpgrade" value="true" /> <param name="initparams" value="AccessMode=Local,User=John Angelini" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/> </a> </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
All we have to do is pass in another param like so and we should be golden:
<param name="windowless" value="true"/>
The result, Voila! We have a Silverlight application that is baked into the page, displays behind the modal dialog, and most importantly, is no longer interactive, allowing our modal dialog to actually be a modal dialog.
10/30/2009
I recently presented at the Philly.NET CodeCamp. While killing time until it was my turn, I attended a session on Test Driven Development (TDD) using NUnit for creating rich unit testing frameworks using Dependency Injection and Mock Objects, given by Len Smith.
While the topic of TDD is certainly one that warrants further discussion, I want to share a development tool I discovered along the way, as part of Len's demo. So I'm watching, and I see all this cool stuff happening in Visual Studio, that Ive never seen before. I see a bunch of code snippet shortcuts, that I KNOW arent in my copy of Visual Studio... and I see this little icon that keeps popping up, and seemingly, with no clicks or anything, this magical stuff happens and code appears.
By this point, I'm watching in amazement, not at what Len was talking about, but about all these neat little things I was dying to ask him about. I start thinking "Is this a new version of the VS10 bits?" but Ive used those, so Nope... wasnt that.
About 10 minutes in, I heard Len say "something something... ReSharper... something something...." RESHARPER... That was the tender tidbit I was looking for. I made a quick note like a good little geek in my non-iPhone, WINMOBILE Phone to make sure I didnt forget to look it up later.
So I get home and download the fully-functional 30-day trial version and install it. (Trust me if youve made it this far, youre buying this!). I fire up Visual Studio... 2008 not this supercharged new VSNext I thought I was seeing. No. Just my plain old vanilla VS2008... now nicely supercharged!
ReSharper is a product by JetBrains that provides solution-wide error highlighting (and one-click fixes), code refactoring, coding best-practice based code validation, ease of navigation between objects in code and their definitions, as well as numerous other functions... and its extensible!
This tool is a must. Within 15 minutes of using it, I was amazed at some of the errors it found, err... I mean suggestions it made for my code! :) I was also very impressed with some of the advanced refactoring tooling it provides. I was able to easily promote methods and properties to base classes and interfaces.
One of the neatest things I saw was the ability it provides to validate string.Format() calls by looking at the number of arguments, and seeing how many placeholders exist in the format string. Another powerful feature ReSharper provides is suggestions for when methods in your code can be marked as static or if your classes can be sealed, static, etc. You really will learn alot about coding best practices from this tool by the suggestions it provides.
Get all the information at their website... Go there... Now. Run, don't walk. Do not pass GO. Do not collect 200 dollars. Download it. Install it. Use it! You can thank me later. :) 7/18/2009One of the most common things I see when working with WPF and Silverlight (and even C# or XML), is a virtually unreadable markup file (or code in the case of C#). The reason for this is because it is all too easy to rely too heavily on the Intellisense feature of Visual Studio, allowing it to add all of our attributes to our XAML tags in a linear, "go until youre done" approach which causes our code to run off the side of the page, and gets real messy.
The first thing you should notice about the example below is that it indeed runs way off the side of the page, which is often the case when we view this type of code in Visual Studio. Specifically notice line 24. In order to view the entire markup for our tag, to get the big picture, we need to scroll, and scroll, and get bits and pieces of what we wish to view.
Consider the following snippet for a standard grid containing some labels, and some text blocks for displaying some bound data in a data template.
1: <Grid Width="600" Height="Auto"> 2: <Grid.RowDefinitions> 3: <RowDefinition Height="Auto" /> 4: <RowDefinition Height="Auto" /> 5: <RowDefinition Height="Auto" /> 6: <RowDefinition Height="Auto" /> 7: <RowDefinition Height="Auto" /> 8: <RowDefinition Height="Auto" /> 9: </Grid.RowDefinitions> 10: <Grid.ColumnDefinitions> 11: <ColumnDefinition Width="Auto" MinWidth="113" /> 12: <ColumnDefinition Width="*" /> 13: </Grid.ColumnDefinitions> 14: 15: <Label Grid.Column="0" Grid.Row="0" Content="Description:" Foreground="#FFFFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 16: <Label Grid.Column="0" Grid.Row="1" Content="Status:" Foreground="#FFFFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 17: <Label Grid.Column="0" Grid.Row="2" Content="Percent Complete:" Foreground="#FFFFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 18: <Label Grid.Column="0" Grid.Row="3" Content="Critical Path:" Foreground="Black" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 19: <Label Grid.Column="0" Grid.Row="4" Content="Start:" Foreground="#FFFFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 20: <Label Grid.Column="0" Grid.Row="5" Content="Duration:" Foreground="#FFFFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 21: <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Path=ProcessDescription}" Width="475" TextWrapping="WrapWithOverflow" Foreground="#FFFFFFFF" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> 22: <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Path=StatusDomainObj.StatusText}" Width="475" Foreground="#FFFFFFFF" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> 23: <TextBlock Grid.Column="1" Grid.Row="2" Text="{Binding Path=PercentComplete}" Width="475" Foreground="#FFFFFFFF" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> 24: <CheckBox Grid.Column="1" Grid.Row="3" Content="" IsChecked="{Binding Path=IsCriticalPath, Mode=TwoWay, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Width="475" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> 25: <TextBlock Grid.Column="1" Grid.Row="4" Text="{Binding Path=StartDelta}" Width="475" Foreground="#FFFFFFFF" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> 26: <TextBlock Grid.Column="1" Grid.Row="5" Text="{Binding Path=Duration}" Width="475" Foreground="#FFFFFFFF" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> 27: <
We could use the built in wrapping feature of Visual Studio, but this tends to muddy things up as well, since we dont know where Visual Studio will wrap the line, based on where the attribute we are looking for is so we are probably going to have just as hard a time finding what we are looking for anyway.
To make our code more readable, we can add a new line to the opening tag, before the first attribute. By doing the first attribute first, we set the automatic tabbing that Visual Studio will use as we move our cursor to the beginning of each successive attribute name, and hit Enter, moving the attribute to a new line.
After we do this for all the lengthy tags (tags with more than two or three attributes, which will cause you to have to scroll to the right to see them) we end up with something like this. Notice the way I also broke up the data binding on line 86 so there is no doubt about where the object boundaries are.
1: <Grid Width="600" Height="Auto"> 2: <Grid.RowDefinitions> 3: <RowDefinition Height="Auto" /> 4: <RowDefinition Height="Auto" /> 5: <RowDefinition Height="Auto" /> 6: <RowDefinition Height="Auto" /> 7: <RowDefinition Height="Auto" /> 8: <RowDefinition Height="Auto" /> 9: </Grid.RowDefinitions> 10: <Grid.ColumnDefinitions> 11: <ColumnDefinition Width="Auto" MinWidth="113" /> 12: <ColumnDefinition Width="*" /> 13: </Grid.ColumnDefinitions> 14: 15: <Label 16: Grid.Column="0" 17: Grid.Row="0" 18: Content="Description:" 19: Foreground="#FFFFFFFF" 20: HorizontalAlignment="Stretch" 21: VerticalAlignment="Stretch" /> 22: <Label 23: Grid.Column="0" 24: Grid.Row="1" 25: Content="Status:" 26: Foreground="#FFFFFFFF" 27: HorizontalAlignment="Stretch" 28: VerticalAlignment="Stretch" /> 29: <Label 30: Grid.Column="0" 31: Grid.Row="2" 32: Content="Percent Complete:" 33: Foreground="#FFFFFFFF" 34: HorizontalAlignment="Stretch" 35: VerticalAlignment="Stretch" /> 36: <Label 37: Grid.Column="0" 38: Grid.Row="3" 39: Content="Critical Path:" 40: Foreground="Black" 41: HorizontalAlignment="Stretch" 42: VerticalAlignment="Stretch" /> 43: <Label 44: Grid.Column="0" 45: Grid.Row="4" 46: Content="Start:" 47: Foreground="#FFFFFFFF" 48: HorizontalAlignment="Stretch" 49: VerticalAlignment="Stretch" /> 50: <Label 51: Grid.Column="0" 52: Grid.Row="5" 53: Content="Duration:" 54: Foreground="#FFFFFFFF" 55: HorizontalAlignment="Stretch" 56: VerticalAlignment="Stretch" /> 57: <TextBlock 58: Grid.Column="1" 59: Grid.Row="0" 60: Text="{Binding Path=ProcessDescription}" 61: Width="475" 62: TextWrapping="WrapWithOverflow" 63: Foreground="#FFFFFFFF" 64: HorizontalAlignment="Left" 65: VerticalAlignment="Stretch" /> 66: <TextBlock 67: Grid.Column="1" 68: Grid.Row="1" 69: Text="{Binding Path=StatusDomainObj.StatusText}" 70: Width="475" 71: Foreground="#FFFFFFFF" 72: HorizontalAlignment="Left" 73: VerticalAlignment="Stretch" /> 74: <TextBlock 75: Grid.Column="1" 76: Grid.Row="2" 77: Text="{Binding Path=PercentComplete}" 78: Width="475" 79: Foreground="#FFFFFFFF" 80: HorizontalAlignment="Left" 81: VerticalAlignment="Stretch" /> 82: <CheckBox 83: Grid.Column="1" 84: Grid.Row="3" 85: Content="" 86: IsChecked= 87: "{ 88: Binding Path=IsCriticalPath, 89: Mode=TwoWay, 90: NotifyOnValidationError=True, 91: UpdateSourceTrigger=PropertyChanged, 92: ValidatesOnDataErrors=True, 93: ValidatesOnExceptions=True 94: }" 95: Width="475" 96: HorizontalAlignment="Left" 97: VerticalAlignment="Stretch" /> 98: <TextBlock 99: Grid.Column="1" 100: Grid.Row="4" 101: Text="{Binding Path=StartDelta}" 102: Width="475" 103: Foreground="#FFFFFFFF" 104: HorizontalAlignment="Left" 105: VerticalAlignment="Stretch" /> 106: <TextBlock 107: Grid.Column="1" 108: Grid.Row="5" 109: Text="{Binding Path=Duration}" 110: Width="475" 111: Foreground="#FFFFFFFF" 112: HorizontalAlignment="Left" 113: VerticalAlignment="Stretch" /> 114: </Grid>
Stacking the attributes (and data bindings) this way makes our code much more readable, and easy to compare to other similar nodes. For example, we might notice that in the example above, the fourth Label control has the wrong foreground color, which would render the text invisible. This type of error is fairly visible when reading down through your code. Additionally, you can process the code much faster when only reading in one direction (down), instead of having to constantly mentally adjust between down and over, down and over. Throw scroll in there as well, and thats the formula for a very mentally trying review of your code. You should hopefully see a noticable difference in your ability to process your code mentally, after adopting this approach.
As you can see by the samples below, this approach works nicely for C# and T-SQL as well. Both editors by default support the automatic tabbing on new lines for the arguments being passed.
C# Before: Person p1 = new Person(){ FirstName="John", LastName="Smith", Email="john.smith@nowhere.com", Email2="jsmith123@nowhere.com", PhoneNumber="609-555-1234"};
Person p2 = new Person(){ FirstName="Sally", LastName="Jones", Email="sally.jones@nowhere.com", Email2="sjones@nowhere.com", PhoneNumber="609-555-2345"};
Person p3 = new Person(){ FirstName="Peter", LastName="Williams", Email="peter.williams@nowhere.com", Email2="pwilliams@nowhere.com", PhoneNumber="609-555-3456"};
List<Person> people = new List<Person>();
people.Add(p1);
people.Add(p2);
people.Add(p3);
Person pOut = people.Where(p=>{return p.LastName == "Jones";}).First();
MessageBox.Show(string.Format("{0} {1}",pOut.FirstName,pOut.LastName));
C# After (Notice the Lambda expression in the LINQ call is also broken out): Person p1 = new Person()
{
FirstName="John",
LastName="Smith",
Email="john.smith@nowhere.com",
Email2="jsmith123@nowhere.com",
PhoneNumber="609-555-1234"
};
Person p2 = new Person()
{
FirstName="Sally",
LastName="Jones",
Email="sally.jones@nowhere.com",
Email2="sjones@nowhere.com",
PhoneNumber="609-555-2345"
};
Person p3 = new Person()
{
FirstName="Peter",
LastName="Williams",
Email="peter.williams@nowhere.com",
Email2="pwilliams@nowhere.com",
PhoneNumber="609-555-3456"
};
List<Person> people = new List<Person>();
people.Add(p1);
people.Add(p2);
people.Add(p3);
Person pOut = people.Where
(
p=>
{
return p.LastName == "Jones";
}
).First();
MessageBox.Show(
string.Format
(
"{0} {1}",
pOut.FirstName,
pOut.LastName
)
);
SQL Before: SELECT FirstName, LastName, ID, Email
FROM People
WHERE FirstName = "John" AND LastName="Smith" AND Email IS NOT NULL
ORDER BY LastName, FirstName, ID
SQL After: SELECT FirstName,
LastName,
ID,
Email
FROM People
WHERE FirstName = "John"
AND
LastName = "Smith"
AND
Email IS NOT NULL
ORDER BY LastName,
FirstName,
ID| Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
|
|
|
|
|