jueves, 26 de agosto de 2010

Aero Glass en ventanas WPF

Una forma fácil y linda de decorar nuestras ventanas , y que ademas quede integrada con Windows, es usar Aero Glass.



Lo que devemos hacer es crear una clase en nuestro proyecto llamada GlassHelper


public class GlassHelper
{
         [DllImport("dwmapi.dll", PreserveSig = false)]

        static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern bool DwmIsCompositionEnabled();
        public static bool ExtendGlassFrame(Window window, Thickness margin)
        {                
             if (!DwmIsCompositionEnabled())
                 return false;
             IntPtr hwnd = new WindowInteropHelper(window).Handle;
             if (hwnd == IntPtr.Zero)
                 throw new InvalidOperationException("ERROR");

             window.Background = Brushes.Transparent;
             HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

             MARGINS margins = new MARGINS(margin);
             DwmExtendFrameIntoClientArea(hwnd, ref margins);
             return true;
      }
}

Luego creamos una struct así:

struct MARGINS
{
    public MARGINS(Thickness t)
    {
       Left = (int)t.Left;
       Right = (int)t.Right;
       Top = (int)t.Top;
       Bottom = (int)t.Bottom;
    }
    public int Left;
    public int Right;
    public int Top;
    public int Bottom;
}

Y en nuestra ventana colocamos esto:
protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e); 
    GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
}

Listo, ya tenemos nuestra ventana decorada con Aero Glass


Timer para hilo gráfico en WPF

Muchas veces queremos usar un timer para realizar algún cambio sobre uno de nuestros objetos graficos, lo primero que se nos viene a la cabeza es usar System.Timers.Timer  pero les voy acontar porque no y cual debemos usar.
Si usamos  System.Timers.Timer en una aplicación de WPF, debemos  tener en cuenta que System.Timers.Timer se ejecuta en un subproceso diferente del subproceso de interfaz de usuario (UI) y esto nos puede dar problema a la hora de ejecutarse al no poder despacharse.
En lugar de eso usaremos DispatcherTimer el cual se ejecutará en el mismo subproceso que Dispatcher dándole a este una prioridad y haciendo que se ejecute en el momento apropiado.

Les dejo un ejemplo donde se apaga una label cuando "algo" por ejemplo esta destrancado:


//  DispatcherTimer setup
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();

//  DispatcherTimer update
void dispatcherTimer_Tick(object sender, EventArgs e)
{
   if (!IsLocked())
       lblLocked.Visibility = System.Windows.Visibility.Collapsed;
}



Por mas info les dejo el link del msdn DispatcherTimer