2010-01-12 8 views
13

Por lo tanto, necesito generar procedimientos para generar una imagen de fondo para una grilla, solo toma .1sec.wpf resize complete

Así puedo conectarme al evento SizeChanged, pero luego cuando cambias el tamaño del gráfico, se activa y dispara incluso 30 veces por segundo, por lo que el evento de cambio de tamaño queda retrasado significativamente.

¿Alguien sabe una buena manera de conectarse al evento de cambio de tamaño y prueba el clima el uso se hace cambiar el tamaño, traté de simplemente comprobar el estado del mouse arriba/abajo, pero cuando el evento de cambio de tamaño dispara el ratón está casi siempre abajo .

+0

¿Cuál es la naturaleza de la imagen? ¿Es un ráster o una imagen vectorial? La razón es que podría haber un mejor enfoque, dependiendo de la naturaleza de lo que estás tratando de hacer. – codekaizen

+0

Es ráster y se basa en algunas matemáticas algo complicadas. No estoy completamente familiarizado con las capacidades del arte vectorial, pero supongamos que por ahora no se puede hacer en xaml. –

+0

@JoelBarsotti: La mejor solución es llamar "GenerateImage()" dos veces en el eventhandler sizechanged –

Respuesta

21

Al cambiar el tamaño, puede iniciar un temporizador de corta duración (digamos 100 mSec), en cada reinicio de ajuste de ese temporizador para evitar que transcurra. Cuando ocurra el último cambio de tamaño, el temporizador transcurrirá, y luego podrá dibujar su imagen de fondo.

Ejemplo:

Timer resizeTimer = new Timer(100) { Enabled = false }; 

public Window1() 
{ 
    InitializeComponent(); 
    resizeTimer.Elapsed += new ElapsedEventHandler(ResizingDone); 
} 

void ResizingDone(object sender, ElapsedEventArgs e) 
{ 
    resizeTimer.Stop(); 
    GenerateImage(); 
} 

private void Window_SizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    resizeTimer.Stop(); 
    resizeTimer.Start(); 
} 
+1

esto parece un poco como un truco, pero hey un truco que funciona es mucho mejor que el código prístino que se rompe. –

+1

@Joel, supongo que esta es la única manera más fácil, porque el cambio de tamaño de la ventana en realidad es hecho por Window Chrome que no es parte de WPF en la ventana nativa, por lo que no obtendrá ningún evento de ratón con el que trabajar. Alternativa es crear tu propio Window Chrome, tu propio estilo de ventana sin bordes y en tu estilo necesitarás recrear todo el marco de la ventana y escribir el código de eventos del mouse. –

+0

Estoy todo por más fácil, piratear o no, si 10 líneas de código son casi las mismas y 1000 líneas, tomaré las 10 líneas cada vez. –

0

¿Es necesario ver el cambio de tamaño de imagen? Puede manejar el cambio de tamaño y volver a procesar la imagen en el evento de mouse arriba.

+0

Eso fue lo primero que pensé, pero cuando lo probé no pude encontrar la manera de detectar el evento correcto de mouseup, soy una especie de WFW newb y me gusta el código de alguien más. El código en el que estaba trabajando se inserta como un elemento secundario dentro de otro objeto. Lo que entiendo es que hay eventos enrutados de burbujeo y túneles, lo que tengo que hacer es capturar la versión de túnel.Según entiendo, esos eventos suelen tener un prefijo Vista previa, y no vi uno para mouseeftbuttonup. –

+0

bien encontré el evento .PreviewMouseLeftButtonUpEvent, pero parece que no se dispara cuando termino de redimensionar. –

2

Para .Net 3.5 y posterior Pete Brown describes una solución con una Propiedad adjunta utilizando Blends System.Windows.Interactivity.dll.

Allí podría cablear el evento de cambio de tamaño para dejar de generar su imagen y en el evento de tamaño modificado comenzar a generar la imagen para el nuevo tamaño.

HTH

0

La mejor solución es llamar "GenerateImage()" dos veces en el manejador de sucesos SizeChanged

1

me gustaría utilizar el método Dispatcher.BeginInvoke. Esto asegurará que su imagen solo se genere cuando la aplicación tenga tiempo para procesarla.

private bool _generateImageReqested = false; 

private void Window_SizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    if (!_generateImageReqested) 
    { 
     _generateImageReqested = true; 
     Dispatcher.BeginInvoke(new Action(GenerateImage), DispatcherPriority.ApplicationIdle); 
    } 
} 

private void GenerateImage() 
{ 
    _generateImageReqested = false; 

    // resize your image here 
} 
4

Aquí está la solución limpia:

private const int WmExitSizeMove = 0x232; 

private void OnLoaded(object sender, RoutedEventArgs args) 
{ 
    var helper = new WindowInteropHelper(this); 
    if (helper.Handle != null) 
    { 
     var source = HwndSource.FromHwnd(helper.Handle); 
     if (source != null) 
      source.AddHook(HwndMessageHook); 
    } 
} 

private IntPtr HwndMessageHook(IntPtr wnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    switch (msg) 
    { 
     case WmExitSizeMove: 
      // DO SOMETHING HERE 
      handled = true; 
      break; 
    } 
    return IntPtr.Zero; 
} 

Buena suerte!