Friday, March 14, 2008

Why InvalidateZOrder is not public???

The worst case of what you can implement on WPF is custom control. In this case you have to use most of the extensebility of the framework, and it turns out that it is just, well, non-extensible...

Today it turned out that there is no way to change the z-order of the element if it's parent is not a Panel, and there is no way I can use Panel as a parent because it tries to steal my logical children :(

It also turned out that there is no way to change z-order without making this:

foreach( Visual child in children )
{
RemoveVisualChild( child );
AddVisualChild( child );
}

And that could be avoided if a method of a Visual, called InvalidateZOrder, would not be internal :(

2 comments:

Joymon said...

Are u Dima working in Artfulbits?
If so I think we had contacted some time back when I was working in Syncfusion..Isnt it?

I hae one solution on this without using add and remove

Just use the GetVisualChild override and return the child as per ur requirement.this vl affect in Z-Order.

public class MyCtrl : FrameworkElement
{
protected override Visual GetVisualChild(int index)
{

//Process index to change the Z-Order
return base.GetVisualChild(index);
}
}

Rat's Blog said...

Hi,

Of course, I do remember you :) How are you?

Regarding your solution - it work only when all the children are rendered first time, and that is the solution I used myself.

But it turned out that after all the children of the element have been reneder once, their z-order is persisted, and it is not enough just to change the order of children in GetVisualChild method to change their order at the display.

When you use Panel as layouter, you can just change the ZOrder attached property, and even when you use your own GetVisualChild method - everything will be fine - zorder of the children will be reset. As the matter of fact, Panel internally calls it's InvalidateZOrder() method of the Visual, but it is internal and I can not call it myself without using the reflection.

And that is why I use the solution, I wrote about, to reset the z-order.

You can try to make some investigation yourself - just try to make GetVisualChild to return element in different order every time (but not diring a single enumeration of children, or you will get an exception) - childrens z-order will not change.