tags:

views:

86

answers:

2

I have a ItemsControl which uses a Canvas as as as the ItemsPanel. The itemsTemplate hosts a Custom Control. When the control is clicked I would like it to "move to the front". I know I can do this with the ZIndex in my control like so:

 private void MyControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if(((FrameworkElement)sender).TemplatedParent==null) return;
    ContentPresenter presenter = (ContentPresenter)((FrameworkElement) sender).TemplatedParent;

    int currentValue = Panel.GetZIndex(presenter);
    Console.WriteLine(currentValue);
    Panel.SetZIndex(presenter, 99);
}

This works and sets the ZIndex just fine. But when I click on a different control in the ItemsControl it will get the exact same ZIndex so it will not "move in front" of the other control.

Basically I just want the same behavior as windows exhibit.

I've tried setting the ZIndex back to 0 in the PreviewMouseUp event, and that ensures that the clicked control is always at the top, but then since all other controls have the same ZIndex of 0 then will assume default order based on there position in the list.

An example:

Lets say I have 3 controls all with a ZIndex of 0. (so they use the default list position.)

If I click on control 3, then 2 then 1. I would expect it to have 3 at the top of the ZOrder, then 2 then 1. But since I'm setting the ZIndex to zero on MouseUp it would have the default order of 1,2,3.

Is there an easy way to handle this or do I need to keep track of the order and increment decrement an arbitrary value such as 99 on my own?

A: 

In my case I set Zindex on selected control and then enumerate all other controls and increment their ZIndex if needed, since at some point you can encounter selected control and all others doen't need to be changed.

Ugly, but so far I have no better solution

TTRider
Yeah i've done this before, but in this case my control has no reference to the control that is hosting it. It's all being done through databinding using MVVM. I'd prefer to keep the control encapsulated.
Kelly
A: 

I would do something along these lines:

Upon mouse down set the Z-index on the selected control to a very high number. Have a static int Zindex initialized to 0. Upon mouse up set the Z-index equal to Zindex++

private static int Zindex = 0;

private void MyControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if(((FrameworkElement)sender).TemplatedParent==null) return;
    ContentPresenter presenter = (ContentPresenter)((FrameworkElement) sender).TemplatedParent;

    int currentValue = Panel.GetZIndex(presenter);
    Console.WriteLine(currentValue);
    Panel.SetZIndex(presenter, Int32.MaxValue);
}

private void MyControl_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    if(((FrameworkElement)sender).TemplatedParent==null) return;
    ContentPresenter presenter = (ContentPresenter)((FrameworkElement) sender).TemplatedParent;

    int currentValue = Panel.GetZIndex(presenter);
    Console.WriteLine(currentValue);
    Panel.SetZIndex(presenter, Zindex++);
}

If your program should be running for a long time you could have some upper limit on Zorder, so if reached you could find the smallest z-index in use and substract this from the z-index on all controls and the Zindex counter.

Falle1234