views:

104

answers:

1

I am developing a UserControl, call it CoolControl, that is meant to act somewhat like a window, with a few special features. So far, it can be resized and dragged all around the screen. If I add multiple CoolControl objects to my application window using XAML, the last one that was declared is always in front. This is fine, but I want to make it so that if I click on one of my CoolControl objects during run-time, that control will put itself in front of all the other controls.

I've tried using Canvas.SetZIndex, but unless I'm simply unable to come up with a clever enough solution, I don't see how that can help me. Because once I set one control's Z-Index to 9999, over time every other control I click will have the same value of 9999. And then, once again, the control declared last ends up in front.

If you were given the task of writing a BringToFront() method for someone's UserControl, how would you do it in the simplest way possible? I'd prefer a better solution than getting the parent window, looping through all the controls, finding the maximum Z-Index, and then setting the Z-Index of the CoolControl accordingly, if THAT is even a valid solution.

+2  A: 

I'm not familiar with the Canvas.SetZIndex method. It looks like some sort of attached property or behaviour.

If you can provide the logic to set the z-index, I've outlined a way to keep track of the instances and manage the z-indexes, keeping them in the order in which they have been selected/created.

public class CoolControl : UserControl
{

    public CoolControl()
    {
        InitializeComponent();
        Instances.Add(this);
    }

    static IList<CoolControl> Instances = new List<CoolControl>();

    void SelectThisInstance()
    {
        foreach(var instance in Instances)
        {
            // decrement z-index instance
        }

        // set z-index of this instance to show at top
    }
}
Jay
Thanks Jay, I hadn't thought of that. I tried it and it works, but it's not really the solution I was hoping for, because if I have controls that have not been added to this list (made by someone else, or just a standard control a guy is including in his window) I would still want my control to jump to the top. I want it to be just like a BringToFront() function that works over all controls. Is there any other solution out there that avoids using a static list?
Dalal
@Dalal I can't think of a way to do it without referencing all of the controls or having all controls subscribe to an event -- at least not in such a way as to preserve the depth of the z-stack based on the history of selection. You could "fake" it by having a transparent `ContentControl` on top and moving a selected control into this, but that would get messy (I'm thinking about sending it back to the original control) and I'm sure it would mess up your existing drag-and-drop/resize/etc. functionality.
Jay
Ah, okay. I think this solution works well though. Thanks a lot.
Dalal