WPF Reflections


November 2, 2007  4:10 PM

Drag and drop by hand

Mark Shurmer Profile: MarkWPF

Drag and drop in WPF is very similar to that in Windows Forms – very very very similar :-) 

If you don’t want to use Josh Smith’s great DragDropManager, either because you want to do multi-select or you want to use a data type other than the type used as an item in the listview, here is what you need to do:

  1. The ListView that you want to have items dropped needs to have the property AllowDrop set to true
  2. You need to implement MouseMove event to do the actual drag drop
  3. You need to implement Drop to actually process the result of what to do when the data is dropped

And that is it
:-)

October 29, 2007  4:28 PM

Drag and drop

Mark Shurmer Profile: MarkWPF

If you find yourself needing to do drag and drop in WPF, and don’t want to do anything fancy try looking at Josh Smith’s drag and drop manager – at http://www.codeproject.com/WPF/ListViewDragDropManager.asp

You use it by declaring a private instance of the DragDropManager with the type of your items:

ListViewDragDropManager<MyDataItem> dragManager;

 Them, create it in your loaded event and attach the ProcessDrop event:

dragManager = new ListViewDragDropManager<MyDataItem>(lv, true);
dragManager.ProcessDrop += new EventHandler<ProcessDropEventArgs<MyDataItem>>(dragManager_ProcessDrop);

and away you go

:-) 


October 26, 2007  1:25 PM

Removing localisation attributes from xaml

Mark Shurmer Profile: MarkWPF

Should you find yourself in a position where you have localised your WPF application, and then wish you hadn’t, you will find yourself needing to remove all the attributes put in by the localisation process.

For those who have yet to experience that, the attribute that is added is x:Uid, like so:

<TextBlock x:Uid=”txtMyTextField” />

The awkwardess is presented by the fact that you want to not only find the attribute in every single xaml element, but to remove the value of the attribute as well.

The first thought I had, no doubt like many others, was that seems pretty basic functionality for search and replace in any xml editor. So I tried my favourite one – no good.
Therefore I tried lots, from basic to industry leaders – even some that half promised on their websites didn’t
:-(

So, I fell back to the last resort which was a regex search and replace in visual studio – which worked, though it’s a whole lot scarier!
Here it is for those looking:

x\:Uid=”[:a\:_]*”

which includes the colon and the underscore in the search pattern


October 25, 2007  3:43 PM

Priority binding

Mark Shurmer Profile: MarkWPF

This is quite a useful binding helper when you are in a scenario where you have a binding to a slow value.
What I mean by that is that sometimes a value may appear in your data source slowly because it is being created via a remote service for example, especially if in the scenario you cannot determine when the value will be received back.

What this markup extension allows you to do is specify a list of bindings, like this:

<TextBlock.Text>
      <PriorityBinding FallbackValue="default text" >
       <Binding Path="Slowest" IsAsync="True">
       <Binding Path="Medium" IsAsync="True">
       <Binding Path="Fast" >
  </PriorityBinding>
</TextBlock.Text>

In this example, assume the slowest takes 8 seconds, the Medium 5 seconds and the Fast is merely nanoseconds
WPF will try the slowest first, but as it’s not there move on to the medium one. That’s not there either so it moves on to the last one, and as that is very fast it will display that one.

What’s even better is that WPF will then display the Medium one after 5 seconds and the slow one after 8 seconds!


October 25, 2007  9:15 AM

Localisation

Mark Shurmer Profile: MarkWPF

Let me firstly describe the localisation support in WPF – absolute pants
For those people who might read this who don’t understand the local London, UK colloquial term pants – it simply means very bad.

Essentially you get the same localisation engine as v2.0 Windows Forms without the design time support. Therefore you can generate csv files for each different culture, edit them, maintain them and recompile to be able to switch languages. It’s a bit horrible though.
Alternatively you can maintain resources for each culture in resource files and bind to them.
There is a good article on code project which describes the three methods localisation in WPF:
http://www.codeproject.com/WPF/WPFUsingLocbaml.asp

VS2008 doesn’t seem to address this either, so I would like the boys and girls in Redmond (et al) to attack this with the same verve as they did the ORM problem. They came up with such a great solution for that, that I don’t think it has sunk in yet just how great it will prove to be.


October 19, 2007  1:29 PM

WPF commands – my view

Mark Shurmer Profile: MarkWPF

Having used WPF for a while, the flexibility in most things is very good

The flexibility that you can do commands as per out of the box method, or using something more strictly command design patterns means that you can decide to go either way on any given project.

What I have I done?
I have recently tended to use the out of the box approach, as for me that’s normally all i want.

If I need undo/redo and/or logging I can derive a class from RoutedUICommand and use that, so I get the best of all worlds.

Just to make it all dizzy, you can also define your own commands by implementing ICommand, but I’ll leave that for another day


October 19, 2007  1:29 PM

WPF command pattern part 2

Mark Shurmer Profile: MarkWPF
SMTP

Following on from my previous post about WPF and the command pattern, how can we avoid the manual process of calling BindToElement from within code? 

What would be nice is if you could specify a commandbinding to point to a static instance of a command, but you can’t. 

But what you can do is create a attached property that will add the command binding for you.
Luckily, someone has been there before –  and a plaudit to Dan Crevier.
See his implementation at http://blogs.msdn.com/dancre/archive/2006/09/15/dm-v-vm-part-7-encapsulating-commands.aspx. How this works is by adding the binding into the code that implements the attached property.

That means your command definition in your xaml can be:

<Button Name=”blah” Command=”{Binding x:Static    gc:RoutedCommands.Exit}}” local:CreateCommandBinding.Command=”{Binding x:Static gc:RoutedCommands.Exit}}” >

And the command is bound to the button automatically, and we are singing and dancing

:-)


October 19, 2007  11:14 AM

Command design pattern and WPF

Mark Shurmer Profile: MarkWPF
SMTP

For an good explanation of GOF version, see http://www.dofactory.com/Patterns/PatternCommand.aspx

How does the command pattern differ from the WPF vision of commands?
Well the most striking difference is that the command pattern is there to provide common functionality for all commands. For example you could add logging or undo/redo functionality into the inheritance chain.
As part of that, the standard way of using the commands in WPF means you have to duplicate the CanExecute and Executed code in different windows. Of course all those places could call through to a common method, but that’s getting messy!

So how do you implement the command pattern functionality in WPF?
Firstly you need to subclass the RoutedUICommand class to add your specific CanExecute and Execute methods, see below.
One problem that is left is how you add a binding for your command to the right place in the visual tree, for example the main form or another dialog or a menu etc etc. There is a method on this class, called BindToElement, that you can call from your code:

cmdExit.BindToElement(frm); 
 

public class RoutedCommandBase : RoutedUICommand
{
private CommandBinding binding
public RoutedCommandBase(string descr, string name, Type owningType)
: base(descr, name, owningType)
{
binding = new CommandBinding(this, Execute, CanExecute);
CommandManager.RegisterClassCommandBinding(typeof(App), binding);
}
public CommandBinding Binding
{
get { return binding; }
set { binding = value; }
}
public virtual void CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
}

///
/// Run the command
///
///
///
public virtual void Execute(object sender, ExecutedRoutedEventArgs e)
{
}

public virtual void BindToElement(UIElement ele)
{
if(ele != null)
ele.CommandBindings.Add(binding);
}

}


October 18, 2007  12:43 PM

WPF and the command pattern

Mark Shurmer Profile: MarkWPF
SMTP

You may (or may not) have noticed, but WPF doesn’t implement the command pattern as per the GOF definition.
Instead it uses the term command to use the same definition in multiple places, but have the functionality specified locally.

As an example is worth a 1000 words (as true now as when confucius said something similar):

With WPF you can define a user defined command, normally as a static member, eg. 

public static RoutedUICommand Exit = new RoutedUICommand("E_xit", "Exit", typeof(RoutedCommands));

Then from any xaml you can reference that command. So lets say you have a menu item and a toolbar item that exit the application from the main window, and (for some bizarre reason) a button on a dialog. All three can reference the same command definition

<MenuItem Command="{x:Static gc:RoutedCommands.Exit}" />
<Button Content="_Exit" Command="{x:Static gc:RoutedCommands.Exit}"  />

The button definition above is used in both the toolbar and the dialog, and pressing all three does the same – well at this stage precisely nothing, as we haven’t told WPF to do anything, but we have achieved our goal of a common command definition.

To get around that, add a command binding to the main form and the dialog and add handlers for the CanExecute and Executed events:

<CommandBinding Command="{x:Static gc:RoutedCommands.Exit}" CanExecute="Exit_CanExecute" Executed="Exit_Executed" />

Now you can place your code in the handlers, and the buttons will be enabled if you set e.CanExecute = true in Exit_CanExecute and put App.Close() in the Executed handlers.

The downside is you have to repeat your code between the main form and the dialog – which leads on to the command pattern as defined by the Gang of Four – http://www.dofactory.com/Patterns/Patterns.aspx, which is detailed in the next post


October 4, 2007  1:11 PM

Sorting listview

Mark Shurmer Profile: MarkWPF
SMTP

ListView (and the default GridView view) is a great bare bones control for us to add extra functionality – though sorting out of the box would have been handy.

On the face of it, sorting is easy – you handle the click of the header and call Sort on the collection being bound to using the property of the header just clicked. What could be hard about that?

Welllll, there are two problems.

Firstly, you would like to make the sorting process generic rather than either repeating code for each header for each grid
Secondly, you need to know which property to actually sort on and which direction. The reason that you don’t always know the property is due to the fact that the property may be in some arbitary point inside a template defined for the column.

Attached properties are the answer to both these problems, as well as a custom GridViewColumn child class.

For problem one, define an attached property to add sorting functionality and then add to the listview definition , like so:

<ListView Name="lvItems" gu:IsGridSortable="True"

Then to solve problem two, use the derived GridViewColumn class like so:
<gu:SortableGridViewColumn Header="Bid tick" CellTemplate="{StaticResource xxx}" SortPropertyName="BidTick" />
The SortProperty property enables you to specify the property that needs to be sorted very easily
Where gu is a xmlns definition to point to your namespace where your new attached property class lives.
Luckily , for you and me, someone has kindly created just such classes, just check out Joel Rummerman’s blog:
http://blogs.interknowlogy.com/joelrumerman/archive/2007/04/03/12497.aspx

You will see on his blog that if you define two styles with keys HeaderTemplateArrowDown and HeaderTemplateArrowUp then that style will be shown in the header as well. So if they are triangles, the header will show them, which is great.

For the listview sorting itself, take a look at the attached property implementation by Mike Brown, at his blog:
http://mbrownchicago.spaces.live.com/Blog/cns!2221DC39E0C749A4!331.entry


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: