WPF Overlays or better Adorner


Introduction

What is an Adorner? An Adorner can be used to draw on top of another element. For example imagine that you have an application that shows data in a ListView. When the user enters a search you want to show a loading status that disables the UI (something like the screen shot below)

Loading Adorner

In such a scenario an adorner comes very handy because you can basically draw a shade over the UI and maybe put in some text… for more info click here.


The Adorner class

In WPF to build an adorner is relatively simple ( well if I can do it anyone can :D ). The first thing you will need to do is to create a class that inherits from the Adorner class. The Adorner class constructor accepts a parameter of type UIElement which is the UIElement that will be adorned i.e the adorner will be rendered on top of this element. So your constructor for the Custom Adorner would look something like this

public LoadingAdorner(Implement adornerElement)
            : base(adornerElement)
{ }

Now that we sub classed the Adorner class and we have our code compiling we can start drawing. To draw you have to override a method from the Adorner class called OnRender. This method takes a DrawingContext as parameter which you can use to draw whatever you like. Let create a small example, let’s draw a Rectangle :)

protected override void OnRender(
    System.Windows.Media.DrawingContext drawingContext)
{
    drawingContext.DrawRectangle(Brushes.Blue, new Pen(Brushes.Red, 1), 
                new Rect(new Point(0,0), DesiredSize));
    base.OnRender(drawingContext);
}

So the code above will draw a blue Rectangle with a Red border.


Using the Custom Adorner


To use the custom adorner that we have created you will need to add it to an AdornerLayer. You can do this by calling the static method GetAdornerLayer of the AdornerLayer class. This method will walk up the VisualTree and potentially find an AdornerLayer which can be then used to render adorners. Once you have an instance of the AdornerLayer you can call the Add method and pass an instance of your custom adorner class. Once you add your Custom Adorner in the AdornerLayer, it will be rendered inside that AdornerLayer without disturbing your UIElement. The code to do this should look similar to this

AdornerLayer parentAdorner = AdornerLayer.GetAdornerLayer(mainPane);
parentAdorner.Add(new LoadingAdorner(mainPane));

Note: If the AdornerLayer.GetAdornerLayer is returning you null it means that you have no AdornerLayer in your VisualTree. You can add an AdornerLayer by using the AdornerDecorator in your XAML. Something like this.

<AdornerDecorator>
    <DockPanel Name="mainPane">
       
    </DockPanel>
</AdornerDecorator>


Some other useful tips


If you want to render a UIElement inside an adorner you will have to communicate this to the layout system so that it knows that it needs to layout the element. Usually you do not do such a thing in an adorner but still you can find this very useful. I used this when I was creating drag and drop for listboxes.

An adorner is also affected by Transforms. By this I mean, if you have a Layout/Render transform on the element being adorned, for example a ScaleTrasform, the adorner will be transformed as well. I encountered this while developing Jasema v2


The Demo Application


I created a small Demo application which is available for download here. The application basically has a relatively simple user interface. Basically I created a Listview that is binding to some data and a search box so that the user can filter that data by name. When the user clicks search, the user interface draws an Adorner signaling a loading status (I created a small hack so that I simulate some workload by using Thread.Sleep(2000). Do not do that in your real life application! ). In this demo I used the MVC design pattern by using WPF commands which is really interesting. For more info on MVC and WPF visit this post.

Download the demo project

GridViewColumn DisplayMemberBinding vs CellTemplate

GridViewColumn has 2 different ways how one can specify the content of a cell. One can use the DisplayMemberBinding or also a CellTemplate. DisplayMemberBinding is used when you just want to show some text inside your GridViewColumn. You can use this property as follows

<ListView>
    <ListView.View>
         <GridView>
             <GridViewColumn DisplayMemberBinding="{Binding Name}"
                                    Header="Name"/>
         </GridView>
    </ListView.View>
</ListView>

So basically all you have to do is specify a binding to the property of the object being bound. In reality the DisplayMemberBinding will create a TextBlock and bind the Text property of the TextBlock to the binding that you specify. Yet if you need more than just text in a TextBlock then DisplayMemberBinding is not what you should be looking for. For such scenario one should use the CellTemplate.

The CellTemplate property of the GridViewColumn allows you to enter a DataTemplate where you can put in whatever you like as controls to be rendered by the GridView. Let me give you an example of how one can use the CellTemplate to do something more than Text

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Image">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Image Source="{Binding Image}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

So in the above example the ListView is now rendering an image where the source of the image is set via a binding to a property of the object being bound to. This gives you much more flexibility in terms of what you can do inside a Cell. For even more advanced scenarios where you have to decide how to render the cell according to the object being bound you can also use the CellTemplateSelector.

Final and most important point about these 2 properties…
DO NOT USE THEM TOGETHER!

If you set the DisplayMemberBinding it is useless to set the CellTemplate because the GridView will only use the DisplayMemberBinding and ignore the CellTemplate. So always make sure that you only set one of these properties and not both at the same time otherwise you will not get the results that you were hoping for.

Want to read some more on ListView? Click here

Consuming Ado.Net Data Services from WPF

I love playing around with new technologies so today I decided to start playing around with ADO.Net Data Services aka Astoria… The first time I saw this technology was a Tech Ed Barcelona… Mr. Pablo Castro himself was showing this beauty! I love this guy….. he is so COOL :)

For those that never heard of Astoria I suggest that you have a look here. Long story short, Astoria gives us an easy way how to pull data out of a data model… So basically you can create a service with Astoria that exposes data in minutes :)

What I will show today here, is how you can query data from an Astoria service from WPF….

So first of all we need a service. Right? :) I will not go into much detail on how to create such a service but you can have a look here for more information. I followed this example step by step and within minutes I had a service up and running :)

Ok ok…. now lets have a look at how we can consume data from this service…

The first thing you will need to do is to create an object model. For example if you want to query data from the Products table you need to create a Product class. You can do this in 2 different ways.
- You can use the Webdatagen.exe (more info found here)
- Create a class manually

I choose to create the classes manually because Webdatagen.exe can give you problems when you have a relational Linq to SQL…. If you do not have any relations then go ahead and use this tool to generate your classes… (Note: You MUST set a namespace for your LINQ to SQL in order for the Webdatagen.exe to work more info here)

First thing you need to do in order to use the Astoria service in WPF, is to add a reference to the Microsoft.Data.WebClient.dll which can be found in the /Program Files/Reference Assemblies/Microsoft/Framework/ASP.NET 3.5 Extensions.

Now it’s time for us to create our mapping classes. The mapping classes are very simple to create. You just have to create a class with properties that have the same name as the properties in the classes generated by Linq To Sql. It is important that the properties that you create have matching names as the properties in the LinqToSql Data model you created otherwise they will be ignored. It is also important to add the Microsoft.Data.WebClient.Key attribute on the property that is the key of your table.
You can also choose to not create all the properties for a specific entity. You can even specify that all properties that are not mapped should go in a Dictionary. In order to do this you can use the ObjectBag attribute and decorate the class you created with it in order to specify which property (of type dictionary) can hold the values of the properties that you choose to exclude from the class…. your class should look something like this now

astoria class

Brilliant! So we are one step closer…. now that we have a class that can hold the data that we are going to get from the Astoria service we need to actually query this service :)

This can be done really easily by using the WebDataContext class. Basically all you have to do is to create an instance of this class and call the CreateQuery<T> method. This method will return a WebDataQuery<T> which happens to implement the IQuerable<T> interface….. Yes! that is right! you can use LINQ to query the service :) so your code would look something like this

astoria query

Is this cool or what ??!!??

Now want to see how you can use all this with WPF ??? download the sample application and have a look yourself…. Please read the read me file supplied in the download for details on how to setup the demo app on your machine

Download Sample Application

WPF TextBox Memory Leak???

While running around in the WPF forums, I found this very interesting post… It seems that the WPF TextBox can be dangerous :) – if you do not use it carefully :)

Basically the TextBox by default stores all text changes in an Undo Stack… This implies that every time that you change the Text of the TextBox more memory is consumed by the TextBox.

In order to fix this you have to set the UndoLimit property to 0. This would disable the Undo feature for the TextBox and thus NO MORE MEMORY CONSUMPTION

Have a nice day

Filtering CollectionViewSource Dynamically

[Please read this post before starting to read this one]

In my previous post I talked about how one can embed code in XAML using the Dynamic Expression API. I was thinking on how to expand this even more. And I figured out… What if I use this for the Filter event of the CollectionViewSource…. Well I tried it out and it ended up working quite well…. What is even better is that you can allow the user to enter a string that is then compiled in a Lambda expression and applied for filtering data :D

So basically my implementation includes an Attached Property that you can use for a CollectionViewSource. This property is called FilterExpression and is in the class called LambdaCollectionView. All you have to do is to pass a string that is the filter expression that you want to evaluate for filtering. As context for your expression there is a predefined variable called item that is basically the type of object that you have in the collection…. example, if you a list of strings you can treat item as a string (i.e you can use all string functions such as StartsWith etc….)
Let’s do a small example on how you can use this. Imagine you have a list of strings and you want to apply a filter that filters all strings that do not start with the character M. you would do something like this

filtering 1

As you can see here you have to use the $ symbol for strings just like in the LambdaValueConverter. Ok ok… so this is cool but what is even cooler is the fact that you can make the user decide how to filter :)

In the demo app I created a textbox and a button. The user can enter an expression in the textbox and when the button is clicked I reset the FilterExpression property and bamm the filter changes… In the textbox the user does not need to use the $ symbol for strings since the textbox handles ” unlike the XAML parser….

filtering 2

This is very handy if you want to apply some basic filtering from the UI…. The filter also supports user friendly expressions like Not instead of != and many others.. For a complete list of supported expressions read the Dynamic Expressions.html under the Dynamic Query folder (inside the download)

Hope you like this and give me more feedback on the AvalonLambdas ….

Regards

Download Source Code

Embed code in XAML

Loads of time I needed a converter that does a very small operation such as binding to the Height of an element and subtract 10 from the binded value. Every time you have to create a converter to do so. I must admit, it really makes me angry because I would like to this in XAML.

I found this cool code sample on Dynamic Expression API from msdn and I thought why don’t I use it to be able to embed code in XAML…. Apparently I am not the first one trying this out . While having a chat with WPF Guru, Josh Smith, he pointed out that someone else created something similar. M. Orçun Topdağı did a very great job in creating converters that can be declared in XAML. Great Job dude!!! It is really unfortunate that I found out about this after I created my own :(

Anyway now that I did it might as well show it to you guys right :) So basically this is quite simple. I created a Markup Extension called LambdaValueConverter that creates an instance of a converter that accepts a LambdaExpression which is then compiled (using the Dynamic Expression API) and run whenever the binding for the converter changes. In order to use this LambdaValueConverter you have to pass the Lambda Expression that you want to evaluate when the binding changes. Let me give you an example. Imagine you want to bind to the Height property of a Grid and divide it’s height by 2 and subtract 20. You would do something like this in the Binding

Binding Lambdas1

As you can see this is quite easy to use… It is important to note that param is a predefined variable that holds the binding value (in the case of this example it will be a Double since we are binding to the height property of a Grid). In the expression you can write anything that is supported in the Dynamic Expression API.

One handy feature I added, is support for strings. Imagine you want to concatenate a string with a binding value. Instead having to create 2 TextBlocks and loads of other things, all you have to do is to enter the text you want + the param that is supplied to you by the converter. You have to surround your string with the $ symbol(don’t ask why I choose this symbol :D ) in order for the parser to know that the specified text is a string. It would look something like this….

Binding Lambdas2

So as you can imagine the output of this binding will be >> The border size is {the value of the binding}.

Cool…. Yet I wanted to go a step further. Basically I asked myself and said, “where can this fit besides for converters” and BAMM… I said what about having such a feature for the CanExecute of commands.. Usually in the can execute of a command all you do is a one line of code yet you have to create an event handler every time (same problem as converters!) So I created a class that inherits from the CommandBinding class and extended it to support a expression string that can be evaluated as the CanExecute event handler. In order to use this all you have to do is, create an instance of the CommandLambdas class and set the CanExecuteExpression property with a string that is your expression. As context of the expression there are two predefined variables that you can use. param that is the parameter that you are passing for the command and e that is the CanExecuteRoutedEventArgs for the CanExecute event. Lets make an example. Imagine that you have a checkbox that determines if the Command for a button can execute or not. The code for the Button would look something like this

Binding Lambdas3

Just for the sake of the demo I used the Application.New command so that I don’t have to create my own :D Ok, so here we are setting the checkbox as our parameter for the command. Now all we have to do is to declare our command binding. We have to declare a CommandLambdas and set the CanExecuteExpression property. Something like this….

Binding Lambdas4

So what we are doing is to check if the checkbox (that is our command parameter) is checked and if it is, we set the CanExecute. The assignment of the CanExecute is being done for us implicitly by the CommandLambdas class.

Updated: I found this brilliant Library called Blendables… in Blendables there is a very impressive feature called SimpleBinding and Complex Binding (among others) that enable you to write code in the binding in a very clean way… much more nice + powerful than what I did here….

So you can do something like this in the binding

Width={blendables:EvalBinding [{Self}.Height]/2}

That’s nice isn’t it…. Have a look at their Documentation here. Or even check out their samples over here.

Well that is all… I am looking forward for feedback to see how we can extend even more this to be even more useful for WPF Developers :)

Looking forward for your feedback.

See also Filterering CollectionViewSource Dynamically

Download Source Code for the AvalonLambdas

kick it on DotNetKicks.com

WPF Date Time Picker

[updated 09th Febuary 2008 - Bug fix for DateTimePicker]
After loads of requests for a DateTimePicker in AvalonControlLibrary I finally had sometime to build a DateTimePicker. DateTimePicker is nothing really special it is a DatePicker and a TimePicker combined in one control.

DateTimePicker exposes an important property called DateTimeSelected. DateTimeSelected is a dependency property so that you can use it in data binding. DateTimePicker also exposes an event DateTimeSelectedChanged that is raised whenever the date/time is changed.

There are some other useful properties that you can set to layout this control

MinuteHand – This property takes a Brush and it is used to color the minute hand

HourHand – This property takes a Brush and it is used to color the hour hand

ClockBackground – This property takes a Brush and it is used as Background color for the clock

CalanderHeaderBackground – This property takes a Brush and it is used as Background for the header of the calander

CalanderHeaderForeground – This property takes a Brush and it is used as Foreground for the header text of the calander

This control also supports control templates. You MUST supply a DatePicker named PART_DatePicker and a TimePicker named as PART_TimePicker in order to create a ControlTemplate for this control.

This control will ship in v2 of AvalonControlLibrary. If you have any suggestions or find any bugs please let me know so that I can update it before I release AvalonControlLibrary v2.

Download Demo Project Here

Please note that a new version is available here

DateTimePicker

kick it on DotNetKicks.com