A: 

Mouse.GetPosition() does not always return a correct value.

Discussion is here

Where this is a problem:
During drag and drop you either have to use the GetPosition() method of the DragEventArgs or resort to get the mouse position through p/invoke.

Documentation (see Remarks).

Patrick Klug
+2  A: 

The WPF layout recursion limit is hard coded to 255 levels.

Based on the complexity of your controls this means roughly 40 - 50 controls.

EDIT: This has been fixed in .NET 4.0

Discussion is here

Quote from Sam Bent (MSFT) in the above mentioned discussion:

The layout system limits depth to 255 (it uses an 8-bit field on each element to store the depth), so you hit the limit when 4N+c > 255, i.e. N ~ 60. [...] The only way to fix the original problem, while still maintaining the standard visual tree structure, is to increase the depth limit imposed by the layout system. This is a hard-wired limit, so apps/users can't change it. WPF would have to re-architect the layout system. Unfortunately for you, there are no current plans to do so.

Where this is a problem:
If you think you can create a tree view or any other nested control that needs to be able to display an unkown or a large number of levels (think Explorer treeview), you are wrong. Even virtualization doesn't help here.

Solutions:
Know this beforehand as you will need to go back to the drawing board and design a control that doesn't nest the hierarchical elements.

Patrick Klug
A: 

WPF and Winforms cannot share the same layout space.

Where this is a problem:
You cannot overlap Winforms with WPF. Wpf popups can also not overlap Winforms elements. You cannot host a Winforms element in a Wpf popup/context menu. (or vice versa)

Solutions:
If anything needs to overlap you have to use separate windows instead of popups. You will not be able to use integration in a context menu.

Patrick Klug
+7  A: 

WPF doesn't call your dependency property getters and setters.

When you create a dependency property, it's conventional to also create a CLR property, so that normal .NET code can get or set the property value. However, many people don't realise that when WPF gets or sets the property value, it goes directly to the backing store.

So there's no point putting validation or coercion logic or change notifications or breakpoints in the setter. They'll run when the property gets set from CLR code, sure, but WPF will just sail past them. Use the PropertyChangedCallback, ValidateValueCallback and CoerceValueCallback instead. And your CLR wrapper should always look like this -- nothing more:

public int Thingy
{
  get { return (int)GetValue(ThingyProperty); }
  set { SetValue(ThingyProperty, value); }
}

Anything else, you're just setting yourself up for confusion!

Note: I know this doesn't have "serious design consequences" per the question, but it is something that seems to prove a pitfall for a lot of people!

itowlson
+1  A: 

When using a WPF ItemsControl that virtualizes (for example a ListView), virtualization is turned off when grouping is turned on.

This can seriously affect the performance for the worse and as far as I know, there are no easy solutions for this.

J W
+2  A: 

Binding to a CLR property (not a DependencyProperty) can cause a memory leak in certain situations. According to the Microsoft Knowledgebase article, "this behavior is by design".

Solutions:

  1. Use a DependencyProperty.
  2. Use INotifyPropertyChanged.
  3. Use Mode=OneTime in the Binding.

You can also programmatically detect problematic bindings when debugging existing code for memory leaks.

Bradley Grainger
A: 

CommandManager.RequerySuggested event is implemented as a weak event.

Where this is a problem:

Although it is clearly pointed out in the documentation most of us probably don't read the documentation for what seems to be an ordinary event.

If you simply add your event handler then you end up with a handler that is simply never called or worse, called just a few times. Debugging this is difficult since you can see the event being registered but then the event handler is lost at some stage.

Solution:

If you want to use this event you need to keep a reference to the event handler yourself. The Documentation says this:

Since this event is static, it will only hold onto the handler as a weak reference. Objects that listen for this event should keep a strong reference to their event handler to avoid it being garbage collected. This can be accomplished by having a private field and assigning the handler as the value before or after attaching to this event.

Example:

{
    //keep a reference to the handler to prevent garbage collection (RequerySuggested is a WeakEvent)
    _requerySuggestedHandler = new EventHandler(CommandManager_RequerySuggested);

    System.Windows.Input.CommandManager.RequerySuggested += _requerySuggestedHandler;
}

EventHandler _requerySuggestedHandler;

void CommandManager_RequerySuggested(object sender, EventArgs e)
{
  //...
}
Patrick Klug
A: 

Creating a field in the viewmodel and then wondering why the * binding doesn't work.

Happens to the best of us.

Turing Complete