views:

116

answers:

1

I have a custom panel for a listbox

<ItemsPanelTemplate x:Key="FloatPanelTemplate">
    <Controls:FloatPanel x:Name="CardPanel" />
</ItemsPanelTemplate>

The panel lays out its children using its X and Y dependency properties. This all works nicely when the FloatPanel is used by itself - I'm using FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure on the dependency properties of the child items to tell the FloatPanel to redraw its layout.

When I use it in a Listbox (code above) then it draws fine the first time, but when I drag the children (which modifies the item's X and Y) it is not notifying the Listbox that it needs to redraw the FloatPanel's children. I think the issue is related to the fact that each item in the bound collection is wrapped with a ListBoxItem.

Hopefully I've described what i'm doing well enough that someone can tell me how to make the panel (or its children) tell it needs to do the Layout routines again. As I said it works once (initial draw) but then dragging items doesn't work (Listbox isnt aware that its children have changed and needs to relayout.) If I drag an item and then resize the window, the listbox does a layout and the items are drawn in their new locations.

How do I notify the ListBox (or more importantly the FloatPanel in the ItemsPanelTemplate) that it needs to do a Layout pass?

+1  A: 
Josh Einstein
Forgot to mention that I have tried those and it did not work. The FloatPanel does not seem to be the parent of the FloatElements inside the ListBoxItems.
Stephen Price
That is true, but then I wonder why it even works in the first layout pass as the ListBoxItem container will always be in between your panel and the item itself.
Josh Einstein
Good point. As a test, I've put an cardPanel.InvalidateVisual(); on the mousemove event of the card panel in the ItemPanelTemplate and it redraws the Panel correctly when I drag the items. So its not an issue of the Panel not drawing correctly, its a problem that the children are not notifying the ListBox that it's changed.
Stephen Price
I think you are probably right that the dependency property changes won't be trigger a layout in the ancestor element simply because of the fact that the ListBoxItem is your immediate layout parent. I'll update my answer with another suggestion.
Josh Einstein
I tried getting the parent of the dependencyobject too. It's null, so didn't work. Just tried to set the parent but the Parent property has no setter. Perhaps I need to add a property to my FloatElement (the child type I put into the FloatPanel) so I can get at it later?
Stephen Price
Ok, I've now gotten it working.basically, I've added a property to my FloatElement the type of FloatPanel. In the loaded event of the FloatPanel I loop through the children and set this property to the parent. Later on in the onchanged eventhandler for the X and Y dependency properties I'm getting the FloatPanel out and calling InvalidateVisual. Its less hacky than calling InvalidateVisual when the mouse moves but still smells. I'm sure there's a better answer out there.
Stephen Price