Wpf Traer al Frente

Tengo un ItemsControl que utiliza un Lienzo como como como el ItemsPanel. El itemsTemplate aloja un Control Personalizado. Cuando el control se hace clic en me gustaría «pasar al frente». Sé que puedo hacer esto con el ZIndex en mi control, así:

 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);
}

Esto funciona y se establece el ZIndex bien. Pero cuando hago clic en un control diferente en ItemsControl va a obtener el mismo ZIndex así que no va a «mover» en frente» de la otra de control.

Básicamente, sólo quiero el mismo comportamiento como el de las ventanas de exhibición.

He probado la configuración de la ZIndex a 0 en la PreviewMouseUp evento, y que se asegura de que el clic de control siempre está en la parte superior, pero, a continuación, ya que todos los otros controles tienen el mismo ZIndex de 0 a continuación, se asume por defecto el orden basado en la posición en la lista.

Un ejemplo:

Permite decir que tengo 3 controles de todos con un ZIndex de 0. (por lo que el uso de la lista predeterminada posición).

Si hago clic en el control de 3, 2 y 1. Yo esperaría a tener 3 en la parte superior de la ZOrder, y luego 2, luego 1. Pero ya estoy configuración de la ZIndex a cero en MouseUp tendría el orden predeterminado de 1,2,3.

Hay una manera fácil de manejar esto o tengo que hacer un seguimiento de la orden y de incremento, decremento un valor arbitrario como el 99 por mi cuenta?

InformationsquelleAutor Kelly | 2010-08-11

3 Kommentare

  1. 5

    Me gustaría hacer algo a lo largo de estas líneas:

    Sobre el ratón hacia abajo fijar el Z-index en el control seleccionado a un número muy alto.
    Tiene un static int Zindex inicializa a 0.
    Al pasar el puntero hasta establecer el índice Z igual a 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++);
    }

    Si el programa debe estar funcionando durante un tiempo prolongado, podría haber algún límite superior en Zorder, por lo que si llegó usted puede encontrar el más pequeño de z-index en el uso y restar este de el z-index en todos los controles y el Zindex contador.

    • Con el fin de desbordamiento ZIndex tendría int.MaxValue clics, e incluso si alguien se hace clic en la increíble velocidad de 10 clicks por segundo, 24/7, que aún tardaría casi 7 años de continuo, sin interrupciones super-clic! Así que creo que no hay nada de qué preocuparse. También, el valor inicial de la estática de los estados ZIndex no debe ser 0, como el primer clic se asigna 1 que podría estar por debajo de otro control ZIndex. Mejor para inicializarlo con 1000 o más para asegurarse de que este método funciona desde el primer clic.
    • Brillante. Esto funcionó para mí en mi (ligeramente diferentes) situación. He eliminado el si() comprobación al comienzo de cada función, y cambió el presentador de la declaración de: ContentControl presenter = (ContentControl)((FrameworkElement)sender); . Gracias por la solución!
  2. 0

    En mi caso me puse Zindex de control seleccionado y, a continuación, enumerar todos los otros controles e incrementar sus ZIndex si es necesario, ya que en algún momento pueden surgir de control seleccionado y todos los demás doen no necesita ser cambiado.

    Feo, pero hasta el momento no tengo a la mejor solución

    • Sí, yo he hecho esto antes, pero en este caso mi control no tiene ninguna referencia al control que se aloja. Todo se realiza a través del enlace de datos usando MVVM. Preferiría mantener el control de encapsulado.
  3. 0

    La forma más fácil es para enumerar todos los elementos de una sola vez y sólo disminuir el índice z si hemos pasado el uno para traer al frente. Esto asegura que el z-index de la parte inferior-la mayoría de elemento siempre tiene un z-index de 0 y el último elemento de un z-index de (count – 1), con cada uno de los que difieren en un número entero de 1.

    Si el aumento (o disminución) de cada uno en cada tiempo, el de llevar a delante con el más alto, el z-index nunca puede empezar en 0 y el resultado final podría ser demasiado contra-intuitivo para su gusto.

    Así que siempre que un elemento debe ser traído a la parte delantera, puede enumerar los artículos como este:

    //If you don't already have the z-index of the item to bring to front (or target item)...
    var i = YourItem.Z;
    foreach (var j in YourListOfItems)
    {
        //Current item occurs after target item in sequence
        if (j.Z > i)
        {
            j.Z--;
        }
        else if (j.Z < i)
        {
            //Curent item occurs before target item in sequence; no need to change the z-index
        }
        else j.Z = YourListOfItems.Count - 1;
    }

    Esto supone enlazar una lista de los objetos a un ItemsControl y los objetos tienen una Z propiedad que se une a Panel.ZIndex de la propiedad en el ItemContainerStyle.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea