« August 2006 | Main | October 2006 »

September 23, 2006

TSA - Covering all options ...

I was recently double checking the current "Permitted and Prohibited Items" list on the United States Transportation and Security Administration website. I couldn't help but laugh when I spotted this one:

Sharp Objects - Meat Cleaver ...

Meat cleavers! Do a lot of air-travelers take their favorite meat cleavers with them in case of a meat cleaving emergency?

September 21, 2006

WPF Layered Windows come at a cost ...

A Microsoft employee, Seema Ramchandani, posted the final word on layered windows in XP: available, but rendered in software rather than hardware. What does that mean? If you've used the recent (June+) WPF bits, you may have seen the new "Window.AllowsTransparency" property. That allows you to create windows that aren't the normal rounded rectangles. Any shape really is possible. The downside is that they won't be quite as fast as they'll be on Vista. Many applications use layered Windows today -- so it's not out of the question to use them still. Just consider whether or not they're really necessary for your application, especially if you're targeting XP and Vista Windows.

Windows UI Top Guideline Violations

A great start to a very helpful document for anyone creating a Windows application (although it has Vista in mind, most of it applies to Xp/2003 applications as well):

Top Guidelines Violations (MSDN)

It's not quite finished and points unfortunately to some uncompleted documents, but it's got a lot of great information.

September 18, 2006

Learn 10 programming languages and get a Job!

eWeek's 10 programming languages you should learn "right now." How many do you know? Any that aren't on the list? How many would you consider yourself an expert in? If you know 10 -- (seriously?) -- are you an expert really in more than 1 or 2 at the most?

Interesting list if you ignore the commentary inline with each language. The explanations for several of the languages is questionable:

6. C

"Why you should learn it: "Learning C is crucial. Once you learn C, making the jump to Java or C# is fairly easy, because a lot of the syntax is common. Also, a lot of C syntax is used in scripting languages," said Duquaine."

Having learned C, C# and some Java, learning C is not crucial. C++ would be a better starting point for Java or C#. And so little of C syntax is used in scripting languages. Curly braces, if statements, and the list doesn't get much longer than that (yes, there are others, but there really aren't that many). The concrete differences far outweigh the similarities.

The person quoted above, Wayne Duqaine also stated: "At last count, I knew/have learned over 24 different languages in over 30 years." Given his comparison of C to C# and Java, I'm not sure how well he really "knew/knows" any of those languages.

Another classic: "Learning C#, which is just Java with a different name plate, is critical if you heavily use Microsoft," said Duquaine.

Yeah. That's all it is Mr. Duquaine. That's like saying OSX is just Microsoft Windows with a different desktop background.

WPF 3D Not ready?

I was experimenting a bit with the WPF-3D features this weekend and noticed this oddity ... (click on thumbnails for larger view):

Monitor 1:

Monitor 2:

What's the difference between these two monitors? The video card. I've got 2 video cards (and 3 monitors) -- when I dragged the window to the second video card's display, the rendering of the image is trashed. Drag it back and everything is fine.

September 13, 2006

WPF Decorators - Build your own "Chrome!"

If you've taken a deep look at how some of the base controls in WPF are constructed, you'll likely have encountered a mysterious element/UIElement at some point, "Chrome." Chrome is a tad confusing when you first encounter it as it seems so magical. Many controls are rendered nearly entirely using these "Chrome" elements (like a Button for example).

One of the first "Chromes" I encountered was actually a Chrome designed for the standard WPF Buttons (ChromeButton). The actual implementation of the "Chrome" for a button may be found in the Microsoft.Windows.Themes namespace. The somewhat interesting part about the Chrome class is that depending on the current user interface style of Windows that is running, a different and unique Chrome assembly is loaded. For example, there's a Chrome library for the Luna (blue XP) theme named PresentationFramework.Luna. There's another for the Vista Aero style named PresentationFramework.Aero.

On my system, the standard WPF button using the Silver XP theme looks like this:

Plain and simple. The button though has some annoying features that make it hard to style any further.

Let's imagine that instead of the standard Silver button, I'd like to make it Green to represent an OK button:

Not too bad so far. The button is green. What about when I actually try to use it ...

Interesting. When I move my mouse over the Button, it reverts back to the original colors. Bummer. What about if I were to click the button ...

Still no green! To say the least, that's a bit annoying. Why Microsoft made the button work this way, I can't answer. I can however provide you with some alternatives.

One solution is to roll your own control template, use the right combination of Borders, rectangles, etc. The sky's the limit. So is, unfortunately, the number of UIElements more than likely. In the first version of WPF that is to be released, UIElements represent an expensive and limited resource in the system, worse in some ways than the old GDI limits, but different in others. Still, it doesn't hurt to conserve, so Microsoft provided another way -- a way to custom render a button like this in a nice reusable pattern. That's exactly what the "Chrome" objects represent in WPF. A fast and lightweight method for rendering a potentially complicated visual. Be warned though that this isn't something that a non-developer would normally do. It's relatively straightforward but certainly outside of the typical non-coder realm. The great thing though is that once developed, it's easy to reference the control either using Expression Interactive Designer or Visual Studio 2005 and use it without understanding how it was built!

My experience has been that it can be EXTREMELY challenging to make some types of "looks" using strictly the UI elements and associated geometries that exist in WPF. Sometimes it seems impossible.

I had a need for a better button. One that would allow me to set different colors AND respect the color in the various typical states (although I have ignored disabled for right now as I had no need. Easy to add though...). The standard button also doesn't provide for a method for changing the border thickness, so I've also provided that functionality.

Here's are the basic steps to creating the Decorator and using it ... (see the attached C# solution with the SmartBorder control and a simple test project that reproduces the screen shot below).

I created a new class library assembly and referenced the PresentationCore/Framework assemblies.

Next, I added a class to the project, deriving from the Decorator base class:

public class SmartBorder : Decorator

To the SmartBorder class, I added a series of DependencyProperty instances for the various necessary properties. For example, here's the CornerRadiusProperty.

public static readonly DependencyProperty CornerRadiusProperty =

DependencyProperty.Register("CornerRadius", typeof(double), typeof(SmartBorder), new FrameworkPropertyMetadata(8.0, FrameworkPropertyMetadataOptions.AffectsRender));

There are two very important steps that must be done to make the new decorator useful: 1) Draw the control, and 2) Measure the control.

The first is accomplished by overriding the OnRender method of the Decorator. Here you're given free access to the DrawingContext (think of this as the place where you draw the series of commands that make up your user interface look). In my decorator, I've used some basic things like the ability to draw a rounded rectangle (see the source code for the other commands I used):

dc.DrawRoundedRectangle(backBrush, borderPen, rc, cornerRadiusCache, cornerRadiusCache);

dc.DrawRoundedRectangle(gradientOverlay, borderPen, rc, cornerRadiusCache, cornerRadiusCache);

Additionally, I wanted to do some drawing which might have occasionally drawn outside of the normal decorator bounds. I didn't want that to happen so I used the clip functionality:

dc.PushClip(new RectangleGeometry(rc, cornerRadiusCache, cornerRadiusCache));

This (and the corresponding dc.Pop) will Clip any drawing commands to the specified shape or rectangle. In this case, I specified a rounded rectangle which mirrors the shape of the button based on the corner radius).

In the override of MeasureOverride, it's the responsibility of the control to respond with the overall desired size of the control. My code simply takes into account the size of the border and adjusts based on the child and returns the overal size. Nothing too complicated.

Additionally, in order to actually use the new SmartBorder, I created a new Control Template:

<ControlTemplate TargetType="{x:Type Button}" x:Key="ShinyButtonTemplate">
<WPD:SmartBorder RenderIsPressed="{TemplateBinding IsPressed}" Background="{TemplateBinding Background}" RenderIsMouseOver="{TemplateBinding IsMouseOver}"
CornerRadius="4"
OuterGlowBrush="{DynamicResource OuterGlowBrush}">
<ContentPresenter
x:Name="ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
Margin="{TemplateBinding Padding}"
/>
</WPD:SmartBorder>
</ControlTemplate>

The SmartBorder is part of the WPD namespace which was declared in the root element of the host:

xmlns:WPD="clr-namespace:WiredPrairie.Decorators;assembly=WiredPrairie.Decorators"

Since my ControlTemplate specifies that all buttons should use the specified control template, it's easy to see the results (actually, only those buttons that don't override the default by using a new style or control template combination):

<Button Background="Aqua">
<StackPanel HorizontalAlignment="Left">
<Label>Big Label</Label>
<Label Style="{DynamicResource ShinyButtonMiniLabelStyle}">Small Label</Label>
</StackPanel>
</Button>

If you have any questions please e-mail. The source code for the sample project and the smart border control is attached (tested only with RC1 of .NET 3.0). If you happen to use the code somewhere / in something, I'd love to know!

WPSmartBorder.zip (41 KB)

If you use VB.NET, just compile the solution and use the WiredPrairie.Decorators.dll in your VB projects by referencing it.

Enjoy.

September 11, 2006

Microsoft Max - The WPF Functional Demo

If you want to see some cool demos of what WPF (AKA Avalon) can do in .NET 3.0, download the WPF functionality demo Microsoft Max. Don't yet bother though if you're not running XP SP2. It won't install on any other version of Windows (yeah, not even Vista RC1). It's a 'smart' download and downloads the pieces that you need (which may include the .NET Framework 3.0 RC1 beta). If you're not comfortable with beta software, I'd suggest staying away for now anyway.

Here's my screen shots of the experience of using Max (the application looks very nice even though it's usefulness is very questionable):

Click the thumbnails for a larger view.

Installation

Splash screen (somewhat slow to load)

First welcome screen.

You'll need a Windows Live/Passport ID to use Max.

The opening screen. Full of graphics and no actual direction as to what I should do next.

News reader (yeah, can't have enough of those installed!)

Added a feed to WiredPrairie. Very nice / interesting layout with automatic graphic reduction to fit the proper space.

Some more news articles:

Here's a picture browser:

Added some pictures to a list (for later sharing I guess, although the software doesn't actually indicate what I'd want to do at any point):

Another view. Interesting, but I couldn't see any reason why anyone would actually want to use this view. Each of the photos/images were individually accessible by clicking on them with the mouse.

Images can be annotated and maybe there was a way to add a caption, but it wasn't obvious. (Hello? I can draw on a photo but not add a caption?)

The photo sharing feature. I wonder if it's using WCF?

Other people's lists (of photos I'd guess). Having no one else that is using this, I didn't have an opportunity to try this (and honestly, by this point, I was already tired of the application).

Summary: Wait till it's released. Maybe it will be something that's worth downloading. But -- I doubt it. The best thing they could do for the WPF community would be to release the source code to this and make it open / shared source. Because as an application, it's entering an extremely crowded market -- a market that doesn't need the odd combo of photo sharing software and a RSS feed reader.

September 3, 2006

Progress on my simple WPF Media Center...

Progress on my simple WPF Media Center clone interface:

You need to upgrade your Flash Player

The animation is pretty close as the list wraps around (an infinite list). The button stays centered yet the text moves. The text fades off on the top and bottom now as well in this new version (which is done a bit differently than the previous screen shots).

I of course used several Storyboard's. The only real trick that I needed was to override the FillBehavior default -- rather than Hold, I needed it to "Stop".

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Height" FillBehavior="Stop">

<SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" KeyTime="00:00:0.25" Value="0.0"/>

</DoubleAnimationUsingKeyFrames>

In this code, I wanted the animation to finish, and then restore the Height back to the original value for the target element (which was set in code rather than being set in XAML). If you don't do this and rely on the default animation behavior, you'll find that the value cannot be set in code. So, in this example, if I try to set the Height to something else like this: myControl.SetValue(Control.HeightProperty, 50.0), the value won't take as the animation is "holding" it at the last value specified in the animation. Sometimes that's what you'd want, but not always. Thankfully, there's an out by using "Stop".

I'm not aware of anyway to simulate the Media Center 2005 user interface entirely from XAML faithfully. In my code, which wasn't very long, I did need to hook several events of the Storyboard to know when the animation was complete:

Storyboard sb = FindResource("HeightToZero") as Storyboard;

if (sb != null)

{

sb.Completed += new EventHandler(HeightToZeroCompleted);

}

September 1, 2006

Microsoft Doesn't need to take a lesson from Apple ...

From eWeek, "Vista Transition: Microsoft Should Take a Lesson from Apple."

While Microsoft's approach to the 2007 launch of Windows Vista is only now coming into focus, it looks as if the Vista experience will stand in sharp contrast to the way Apple pitched the Mac community on its OS X transition.

Has the author, David Morgenstern, actually done any research into the difference between the upgrades of OS 9 to OSX and XP to Vista?

Mr. Moregenstern -- the difference between these two upgrades as you put it is much more fundamental than your sensetionalist article claims. OS X couldn't run old OS 9 and below software. Period. Vista on the other hand should run the vast majority of Windows (and MS DOS) software right out of the box. An upgraded Vista machine should be able to run not only older software, but newer software that takes advantage of new Vista features.

Apple chose not to "push" OSX to customers initially - because the product wasn't ready, and there wasn't much industry support for it. They knew that and made a smart choice. But Microsoft isn't leaving all of it's users out in the cold with an upgrade that isn't compatible.

It's not like Microsoft is switching processors and AGAIN leaving users out in the cold (or at least minimally with poorly performing software like the Adobe multimedia products). That was Apple.

WPF Media Center 2005 Fake-Out

Some experimenting this evening with WPF:

Done completely in WPF without any code. It doesn't yet have the cool sliding animation that the Microsoft Media Center uses, but it's nice looking nonetheless! The active option glows much like the Media Center and the edges of the list fade into nothing-ness just like the real thing. I just eye-balled the original so the colors aren't exact matches by any means (I wasn't going for exact match, just the spirit of the MediaCenter).

To do the faded list of buttons, for the purposes of this demo, I used an opacity mask like this:

<ScrollViewer Opacity="1" Margin="165,92,191,104" x:Name="ScrollViewer" VerticalScrollBarVisibility="Hidden">
<ScrollViewer.OpacityMask>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<TranslateTransform X="-0.5" Y="-0.5"/>
<ScaleTransform ScaleX="1.0141371299213975" ScaleY="1.0141371299213975"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="-89.602136078970744"/>
<TranslateTransform X="0.5" Y="0.5"/>
<TranslateTransform X="-0.010563229438366996" Y="0.0035211220837406574"/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Offset="0.48717948717948717" Color="#FF000000"/>
<GradientStop Offset="1" Color="sc#0, 1, 1, 1"/>
<GradientStop Offset="0" Color="sc#0, 1, 1, 1"/>
<GradientStop Offset="0.85897435897435892" Color="#FF000000"/>
<GradientStop Offset="0.14102564102564102" Color="#FF000000"/>
</LinearGradientBrush>
</ScrollViewer.OpacityMask>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center" Width="Auto" Height="Auto" x:Name="StackPanel" ClipToBounds="True" CanVerticallyScroll="True" Margin="0,0,0,0">
<Button Height="38.106666666666" x:Name="Button_Copy3" Content="Expression"/>
<Button Height="38.106666666666" x:Name="Button_Copy4" Content="XAML"/>
<Button Height="38.106666666666" x:Name="Button_Copy5" Content="VB.NET"/>
<Button Height="38.106666666666" x:Name="Button_Copy6" Content="Microsoft"/>
<Button Height="38.106666666666" x:Name="Button" Content=".NET" Width="284"/>
<Button Height="38.106666666666" x:Name="Button_Copy" Content="C#"/>
<Button Height="38.106666666666" x:Name="Button_Copy1" Content="Web"/>
<Button Height="38.106666666666" x:Name="Button_Copy2" Content="2D/3D"/>
<Button Height="38.106666666666" x:Name="Button_Copy7" Content="Button"/>
</StackPanel>
</ScrollViewer>

Help support my web site by searching and buying through Amazon.com (in assocation with Amazon.com).