Categories: WPF
Posted by
mheydt on
1/22/2010 11:44 AM |
Comments (0)
Last night I posted about a way to do glass effects in your WPF application. The technique I showed was very basic, just showing how to extend glass into the client area. In a lot of cases, you will want to do a lot more. An example is that it is desireous to put a background image behind the entire window. This would seem to be very straightforward with some XAML as such:
<Window x:Class="SocialBus.Navigator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Hello there" Height="350" Width="525" Icon="Assets/Icons/transparent.png" Background="Transparent">
<Grid>
<Border BorderBrush="Transparent" BorderThickness="0">
<Border.OpacityMask>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Offset="1.0" Color="Black" />
<GradientStop Offset="1.0" Color="Transparent" />
</LinearGradientBrush>
</Border.OpacityMask>
<Image Source="Assets/images/pdc09black.png" Stretch="UniformToFill" />
</Border>
</Grid>
</Window>
What this xaml is trying to do is use the pdc09 image as a background, with a linear fade of the opacity from 100% at the bottom to 0% at the top. Unfortuantely, the result is not what I desired, as there is still non-client area on the window that the image is not behind (although I have made the opacity 100% for this image to show the issue better):

The solution to this seems to be involved in intercepting the WM_NCCALCSIZE message to the window, and munging the data to tell the window to have the client area cover the whole window. After many hours of trying to get that to work I just gave up on it and went for another solution.
Another great article on glass effects (chrome) is at this link:
http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx
The article itself is quite informative, and states that dealing with the WM_NCCALCSIZE method is not trivial. Fortunately, that writer also has a library that helps out greatly, and you can get it here:
http://code.msdn.microsoft.com/chrome/Release/ProjectReleases.aspx?ReleaseId=1505
I examined this code and it appears very robust, as it handles all kinds of issues with WDM. Nice thing is that it is very easy to use. Just link the DLL into your project, and for the desired effects I just change the XAML to the following:
<Window x:Class="SocialBus.Navigator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ext="clr-namespace:System.Windows.Extensions;assembly=Chrome"
Title="Hello there" Height="350" Width="525" Icon="Assets/Icons/transparent.png" Background="Transparent">
<ext:WindowChrome.WindowChrome>
<ext:WindowChrome
ClientBorderThickness="-1" />
</ext:WindowChrome.WindowChrome>
<Grid>
<Border BorderBrush="Transparent" BorderThickness="0">
<Border.OpacityMask>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Offset="1.0" Color="Black" />
<GradientStop Offset="1.0" Color="Transparent" />
</LinearGradientBrush>
</Border.OpacityMask>
<Image Source="Assets/images/pdc09black.png" Stretch="UniformToFill" />
</Border>
</Grid>
</Window>
Note that all I did was add the reference to the DLL and add the one tag, which does a lot of magic in the background configuring the window for custom chrome. The result now is the following:

Perhaps still not quite what I want, but what is going on is that all non-client areas are removed and the image takes up the whole window. With a simple tweak, I can make this much better, by putting the gradient fade back in as well asrounding the corners of the image a little (note, I also changed this a little so that instead of using a border I used a rectangle - border wouldn't clip the image corners round):
<Window x:Class="SocialBus.Navigator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ext="clr-namespace:System.Windows.Extensions;assembly=Chrome"
Title="Hello there" Height="350" Width="525" Icon="Assets/Icons/transparent.png" Background="Transparent">
<ext:WindowChrome.WindowChrome>
<ext:WindowChrome
ClientBorderThickness="-1" />
</ext:WindowChrome.WindowChrome>
<Grid>
<Rectangle RadiusX="10" RadiusY="10">
<Rectangle.Fill>
<ImageBrush ImageSource="Assets/images/pdc09black.png" Stretch="UniformToFill" />
</Rectangle.Fill>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Offset="0.0" Color="Black" />
<GradientStop Offset="1.0" Color="Transparent" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
</Window>
And the result: just beautiful!

Glass, transparancy of the whole window, and with a custom background. Kewl! And by the way, drag at the top, min, max, close resize on all edges still works perfectly.
There's alot more that can be done with this library, but this is exactly what I ndeeded.
7b998b8f-faf2-461d-aa9f-f5ede3f49d56|0|.0
Categories: WPF
Posted by
mheydt on
1/21/2010 10:18 PM |
Comments (0)
Today I downloaded the freshly released Seesmic Look application. This is a twitter client that I think makes really great use of WPF. Here's a screen shot:

There are a number of great things going on here, one of which is the use of Aero glass in the WPF application. Notice how the desktop wallpaper blends through the upper part of the window. This is a pretty simple thing to do, but not well documented. There are a few links to information on how to do this that I'll enumerate here, as well as show how to do this in a sample application.
There are a number of great things going on here, one of which is the use of Aero glass in the WPF application. This is a pretty simple thing to do, but not well documented. There are a few links to information on how to do this that I'll enumerate here, as well as show how to do this in a sample application.
The two links that I found useful are:
http://blogs.msdn.com/adam_nathan/archive/2006/05/04/589686.aspx
http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx
Adam gives some code for doing this trick in WPF. I'll reproduce the entire code of the class and an implementation for completeness.
The class for forcing glass into your window is this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Interop;
namespace SocialBus.Navigator.Glass
{
public class GlassHelper
{
[DllImport("dwmapi.dll", PreserveSig = false)]
static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);
[DllImport("dwmapi.dll", PreserveSig = false)]
static extern bool DwmIsCompositionEnabled();
[DllImport("user32.dll")]
static extern uint GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
private const int GWL_STYLE = -16;
private const uint WS_SYSMENU = 0x80000;
struct MARGINS
{
public MARGINS(Thickness t)
{
Left = (int)t.Left;
Right = (int)t.Right;
Top = (int)t.Top;
Bottom = (int)t.Bottom;
}
public int Left;
public int Right;
public int Top;
public int Bottom;
}
public static bool ExtendGlassFrame(Window window, Thickness margin)
{
if (!DwmIsCompositionEnabled())
return false;
IntPtr hwnd = new WindowInteropHelper(window).Handle;
if (hwnd == IntPtr.Zero)
throw new InvalidOperationException("The Window must be shown before extending glass.");
/* Set the background to transparent from both the WPF and Win32 perspectives */
window.Background = Brushes.Transparent;
HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
MARGINS margins = new MARGINS(margin);
DwmExtendFrameIntoClientArea(hwnd, ref margins);
return true;
}
}
}
Now to get the window to use this, we just need to hook up the OnSourceInitialized event/override in the main window control of the application as such:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using SocialBus.Navigator.Glass;
namespace SocialBus.Navigator
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
}
}
}
When running this, the window looks like this:

Very nice! Notice also that I have removed the system icon and title from the window. The title is easy to remove by just setting the Title in the xaml to "". The icon is a little more difficult. You just cant set the Icon property on the window control to null, as WPF takes that as meaning that you want to use the default icon. What you need to do is prvoide a transparent icon. At first I was wondering how you make an .ico file with a transparent background (I dont think you can actually). But fortunately the flexibility of WPF allows for using a .png file for an icon, so I just made a 16x16 png file that was all transparent.
To follow up this post, I actually have some nice twitter control in the works and will add those to this window to show how nice things can look with this technique.
6a2c664b-457a-4f39-9d6a-ef0a58b6cdd3|2|5.0
Categories: WPF
Posted by
mheydt on
7/9/2009 1:55 PM |
Comments (0)
I got word through twitter a few days ago that Telerik is making available to MSDN subscribrers their WPF controls for FREE!
Go and get them! I consider Telerik controls the easiest to use and this is just great to get a perpetual license.
The word I got said this is limited until the end of July, and that you have an MSDN account. When downloading I did not see a need to enter MSDN subscriber information (which I am a member), so try getting them while you can.
94e70e87-c0d9-40f0-b272-fb04ab4eb34d|0|.0
As part of all of this research into Amazon cloud computing I've started to program against the API's to see how they work. Eventually I'd like to build a client that does a lot more than what can be done with ElasticFox, which is a great tool, but falls short when you try to do things that require multiple steps. For example, one scenario that I'm already repeating all the time is the following:
1) Launch AMI
2) Mount 2 volumes to it (one step for each)
This isn't very difficult to do, but imaging if I'm building out managed services on behalf of other clients of mine, and the # of clients gets large, such that this will actually start to take a lot of time in the aggregate. I'd like to have a tool that can do this automatically, and it is possible to program this to be done through the web services.
Another scenario that I'm thinking will be useful is to be able to do automated backups of AMI's and / or volumes, and perhaps also roll back AMI's and / or volumes on a regular schedule. Again, not too hard with ElasticFox, but again a manual process that doesn't scale well.
So, I've started programming a WPF client using one of the C# api's available on the Amazon site, the
C# Library for EC2. It's been pretty easy to use so far, and I wanted something C# based instead of pure SOAP / REST. There are deficiencies in the library that I will address later, but I wanted to show what I've done so far even though it's really just proving to myself that this works.
The following is a control that I put together to manipulate S3 buckets. It's a listbox that is databound to the results from the 'listAllMyBuckets' method on the AWSAuthConnection class in the C# library:
Indeed, these are the two buckets that I have right now.
For reference, I include the XAML and the code behind for the control:


I've also coded this to show me my running AMI instances, but I'll save space here and not post that.
As I mentioned earlier I consider this library to be good but also to have a few deficiencies which I am going about fixing, and I'll probably post these changes back into the amazon code samples. My two big issues at this point with the library are:
- All the calls are synchronous, and
- The "business objects", like 'Bucket', do not utilize INotifyPropertyChanged
The first causes the UI to lag when the calls are waiting to complete. This could be addressed by running these calls in a background thread, but that only solves this for WPF. Inherently, this library will not work under Silverlight as all calls are asynchronous in Silverlight. So, all these calls need to be made to be asynchronous to support Silverlight, which I definitely want to use the library with.
The second point prevents a lot of the nice databinding capabililities, particularly two-way binding, in WPF and Silverlight. As an example, suppose you are monitoring an AMI initializing and want to change the UI when the state changes. The UI control will be bound to a 'RunningInstance' class object, and will show the current state of the instance. You'll then need to poll occasionally to see if the state changed, and when it does, you will currently need to change both the property value in the RunningInstance object, and then also code the change to the UI as the property will not advise any listeners of it's change.
Both of these aren't bad design issues in the library, as when it was built I'm sure it was not with the intention of being used in WPF and Silverlight. So, I'll fix them up and put them back in the Amazon code samples. I'll address the property update problem first as it is more important to me right now, and then handle the async calls afterwards.
Edit: I've since looked into this and to me it seems that it will be far less work to just rewrite the library. In addition to not taking advantage of either INotifyPropertyChanged, or using asynchronous calls, there are also great advantages to be had in using LINQ 2 XML to parse the results. Currently, this is all done with XSLT, and that's just way too complicated when you can use newer language constructs.
Another decision that I've come to is that since I'm going to work on rewriting this instead of extending it, I'm going to post the new code on Codeplex instead of back at Amazon. I've actually created the project and it is here
http://www.codeplex.com/AmazonAWSSharp. No code yet, but hopefully some basic S3 stuff in the next few days.
6e8e817e-feb2-41a2-bcd3-94dce739cd0b|0|.0
Categories: WPF
Posted by
mheydt on
11/6/2008 3:34 AM |
Comments (0)
This is a list I need to grow over time to answer this question. Besides the fact of vector based scalable graphics, WPF has the following advantages:
- Ability to accomplish much of the app in a purely declarative model
- Ability to very effectively separate UI from logic
- Dependency property model
- Command model, including routed commands.
- Bubbled and tunneled events. Many times its so much easier to let events bubble up to a unified listener and make a decision on what to do based upon the original source, or the last control to bubble / tunnel the event. This just lets your centralized a lot of the UI processing logic for a form at the form level, instead of splattered all over the individual controls.
- Built in animation models, including story boarding
- Styling and themes
- Better UI threading model
- Visual state management. Yeah, still just in Silverlight, but coming to WPF soon.
- Declarative model translates to other environments (ie, Silverlight)
- Databinding is LIGHT YEARS more advanced. More on this later.
- Tying into data binding and dependency properties, the observablecollection model is much more robust
- Data and control templates which provide flexible modeling (and substitution) of UI on data models.
- User interface virtualization is built in, allowing handling of extremely large data sets
- 2-Pass layout model. This is real important is it allows negotiation of layout, and control by the container of other controls to modify positioning of element.
- Attached property model, which provides great flexibility in allowing a child of a parent element to talk to the parent in its own language, even though the child has no idea what the type of the parent is. Want to position a text block in a canvas? Use Canvas.LeftProperty. Want to position it in a grid column, use Grid.RowProperty. The child is agnostic to the type of the container, and you make the design time decision on how to pair them up without having to add any code to the child.
- Declarative triggers. Just great to be able to trigger declarative code based upon various events with more declarative code. Much more flexible than doing code behind.
- 3D (yeah, that's part of the obvious vector graphics)
- Ability to easily integrate different types of media out of the box
- Extensive support for different layout models (grid, canvas, stack panel, wrap panel, ...)
- Ability to create interfaces dynamically, or to download and execute them dynamically
- Winforms controls can be used via interop in a WPF app (helps support your installed base)
- Did I say databinding is more advanced? I just love databinding to XML. Additionally, combined with Linq and anonymous classes, databinding is just so much more effective and simple to implement.
- Control creation and reusability. Actual creation of controls is about as easy, but you can reuse controls in WPF so much more effectively. Basically any other control can be the content of another control, allowing great flexibility in building UIs.
- Ability to declaratively use business objects in the UI. Your programmers can build the business objects, package them in a library, and then you can instantiate instances of them in xaml as resources and bind them directly to controls. All without and code on the UI side.
- Preview event model, letting you intercept and perhaps prevent / modify events before they are processed. Brilliant!
Also, and this is a gut feeling that I find hard to quantify, but it just seems that I am significantly more productive in WPF than in WinForms. I think this comes from the ability to quickly layout items, get them bound to data, repurpose the UI if needed, all without much code just seems so much more productive.
Sure it took me understanding all of the items above, but once they are understood it's just really a much more productive environment.
15915584-2552-48f9-97b8-e610a9bf246f|0|.0
Categories: .Net, WPF
Posted by
mheydt on
10/27/2008 3:37 AM |
Comments (1)
I got a request for the code for the perspective background I used in one of my previous posts. It took me a bit of looking, but I dug it up. It's actually a WPF user control, and in the designer it looks like this:

And the xaml is as follows:
You can download this XAML in this
zip file.
45655f84-dba7-4e2e-9d03-b53d7b47e010|0|.0
Over the last few days I've added the capability to specify a different UI element for the nodes of the graph. This picture shows the use of circles for the nodes. Yeah, not too fancy, but its important moving forward. I also added the ability to drag the nodes; that's actually a lot for fun.
One of the things that I did do when working in the drag functionality is to enable the framework to do the dragging. I wanted this so that the programmer of the node need not worry about intercepting mouse events and handling the repositioning.
This was actually an interesting challenge. Since the nodes can be of arbitrary shapes (rectangles, ellipses, polypolygons, ...), the framework can not know what the shape is and hence how to determine if the mouse is down in the visual element.
But wait...
What I did and something that Silverlight / WPF supports quite nicely, is that when the framework calls back into the client code to request creation of a node, the node can support a particular interface, and the framework will check for that interface on the node. If it not supported, you do not get automatic drag. If it is supported, it supports a single method that the framework will call that returns a UIElement to the framework that the framework will bind the mouse events to call into the framework.
This is interested for a few reasons. First, take the sample shown above. The XAML for the node is the following:
This is fairly straightforward XAML. There are three elipses, the first two which form the teal background and white edge, and the third, which is named dragElement, that is for all intense purposes transparent and overlies the other two ellipses.
When the framework requests the UIElement to bind the mouse events to, this codebehind on this xaml returns the ellipse named drag element. That element is then used to do dragging of the whole control.
There is a few subtle reasons why things are needed to be done this way. For example, if you trapped the mouse events on the top level UserControl, mouse events outside of the ellipse but within the rectangle will also cause dragging. Not good.
If you make it the white edge ellipse, then mouse events are only handled when the mouse is ac actually over the stroke, not inside the ellipse. I found that interesting.
If you make it the Teal ellipse, then the border ellipse, being on top, prevents mouse events from going through when over the border of that ellipse.
Note: I realize I could use just one ellipse with a teal fill, and a white border. However, if you notice, the opacity on the elements are different. I wanted the teal to be slightly transparent, but I want the border to be totally opaque.So, what I did is create the third ellipse, make it transparent, and to cover the exact size of the other ellipses. This provides the drag capability I want, all with just supporting an interface and coding one method.
Note: I may change this model in the future. This works well, but there may be better ways. One way would be to create a property that can have an attribute that the framework looks for. That might be better as it won't clutter the class definition with interfaces. I don't know, I'm kind of 50/50 on that for now.n If you've got an alternative way, let me know.
This model also will play nicely with irregular shapes as the UIElement returned could be a polygon, and all things should work the same.
Note: There are a few interesting things about the way this is programmed that I want to document in the future. A lot of times in OOP to create a new control that would use different visual element, you might subclass the control and override virtual methods. In this model, the framework uses events to request data from anyone that may be a client of the control. I find this a lot cleaner as you get a better separation of concerns. I'll elaborate on this more in another post.
It's late now and I have a busy day tomorrow.
I'm also going to try and post a live version of this control during the week.
52ac2ba2-cbce-4a74-9dab-a4a62c65406c|0|.0
I've gotten a few requests about the force directed graph
post that I made several months back. Seems that this is a popular topic for people trying to find code to do this, and I've been asked several times to post the code.
First, I don't know how robust and scalable this control is, as I was only writing it to learn some WPF control templating. Also, I modeled the engine off of some code in another open source project that is GPL. I say modeled as I literally wrote my own off of that code, but because of that it is somewhat similar, so I wonder about distributing my code before I do some checks into licensing. Until I figure that out, you can get the code that I started with over at the
Netron site and do similarly to what I did. Note that the code in that project supports a lot more functionality, is highly intertwined with WinForms code (not WPF), and that is where I spent most of the time converting things into an engine that only does force directed layout, is seperate from the UI, and of course with a WPF interface.
And, as I mention in this
post, I've actually moved on with creating what should be a much more robust force directed graph control using the C++ boost graph library wrapped with C#. That code is in a really early stage and not worth posting at this point, but given the interest I may very well try to get it better and posted for everyone. That is free to distribute if that time ever comes. Unfortunately, it does not work quite as well as the former project at this point as I am still learning how to do the C++ to C# integration.
ad72f216-9b79-4ef8-a11c-561c54259197|0|.0
Some notes on this podcast that I think are of importance...
Ted states that event based programming differs from event driven systems. An example of an event driven app is a windows GUI. These event driven programs do nothing until receiving event and then handle it internally. Event-based applications, on the other hand, basically operate upon upon internal communications between different parts of the application that are hooked together to provide functionality through event based communications.
Dynamic Routing is stated as being one of the important things about this type of programming. Dynamic routing is where handlers for events can be changed at run-time. In event based systems this is fixed at runtime. Event-based applications can change the configuration on the fly. To do this, several constructs are used:
- Builders - instantiate all the objects in the system
- Binders - provide communications channels between systems
- Coordinators - provide orchestration between objects through binders
The key point is that binders preserve the decoupling of sources of events from their listeners. This is important to be able to ensure flexibility, independent development, and independent testing of the components. A builder puts together all entities that will be wired, and then passes control to a binder which wires the individual components. Binders then wire up all the observers to subjects.
description of switch statements being used as a means for demultiplexing data moved over a single communications channel. At some point some data is created, then through one code path (the communications channel) a decision is made to go different ways. This inherently bad for concurrency and scalability, and handling through bindings is much more scalable.
Also raised was a concern about the .NET/WPF model of events and passing argugments to the event through classes as a parameter. To create your own events, you must necessarily then create an event arguments class. This therefore causes class explosion as you need to make a new class for every event just to pass the arguments. I totally agree with this as I think its a total pain to have to go through this.
Ted has a book on this topic. I have not read it yet: Event-Based Programming: Taking Events to the Limit.
I'm curious to see if he gets into topics of Invasive Software Composition. I recommend the book on this by Uwe Assmann. This book discusses a number of topics, but which I would describe as mostly discussing AoP and connection of software components through connectors, ports and adapters. It's also a good read if you are into SOA and BPEL, as (at least to me) it gave good clarification on the use of communications channels (SOAP/REST) between components (Web Services) and transformation (XSLT) of data (XML) across the channel.
Where this ties into the discussion that Ted had is that Assmann (boy that's a bad name in the US) would do the "binding" with AoP constructs, basically injecting the bindings between the components at runtime through dependency injection (DI). I would also tend to say that the bindings could not also be done this way, but also through generic programming using policy classes, as well as havnig routes between objects be able to be modified dynamically through having the injected policies either change or make decisions on the data.
This last point gets into another SOA tennant (a reason I brought it up earlier) which is know as content based routing. Typically, this is done on an enterprise service bus through logic attached to the bus, but within an application, a very flexible model of routing of data as well as code flow could be set up with a good combination of AoP, DI and event based architecture.
875f1909-84e3-4fb1-abfb-dfa93c2a7791|0|.0
I ran across this good post today while searching on using objects represented as a MonoState or Singleton pattern in WPF databinding:
Monostate vs. Singleton : Adventures in WPF Databinding [The .NET Addict's Blog]
The gist of it is that objects represented as a MonoState may not work property with property update notifications. This kind of makes sense as the UI will be bound not to the actual object, but the wrapper around the internal singleton. Hence, property change notifications on the singleton may not make it up to the UI since they bubble up but there really isn't anywhere to go as they are not actually bound to a UI control.
So, the summary is be careful if you do this.
d71931ac-7fb7-4e61-b150-fd62d7bab12e|0|.0