martedì 8 febbraio 2011

WPF Ribbon

Ribbon Control Updates
Straight from the update details document, here's what was updated in this version:
  • Ribbon Split Button is only half-highlighted when users mouse over the button
  • Ribbon Title is bottom-aligned, should be centered
  • Ribbon Quick Access Toolbar icons are clipped and top-aligned
  • Ribbon Contextual Tab header text is getting truncated if too long
  • Ribbon Gallery Item does not stretch to fit its Parent Panel
  • Initial enabled state of Ribbon Split Menu Items can be incorrect if they have children
  • Ribbon Split Menu Item with sub-items is disabled if CanExecute=false
  • WPF Ribbon Dropdown does not close when CanAddToQuickAccessToolBarDirectly="False" was set at various level within the Ribbon
  • InvalidOperationException may occur when switching themes and the WPF Ribbon is Minimized
  • Ribbon Tab Header content may not appear when Ribbon starts out collapsed
  • RibbonTab.TabHeaderLeft & RibbonTab.TabHeaderRight are incorrect when Ribbon starts out hosted in a Collapsed control
  • Ribbon Tool Tip: Title and Footer Title gets clipped if the stringis too long
  • Vertical and horizontal alignments for the standard Ribbon controls should be centered, they were not.
  • After removing all items from the Quick Access Toolbar, phantom items remain visible
  • Right clicking on the System icon will not place the Context Menu properly
  • System Icon, Title and Quick Access Toolbar are not displayed correctly when Ribbon Windows is maximized
  • A minimized Ribbon will render on top of the window when a Popup is opened.
  • RibbonWindow.Icon does not pick appropriate small size icon from *.ico Icon file.
  • IndexOutofRange Exception would pop when removing a Tab from an Observable Collection.
  • WPF Ribbon can use ClearType when targeting .NET Framework 4.0 control.
The two most important fixes in here for me are the cleartype fix, and the support for the Express SKUs. You know I go nuts overproper ClearType rendering.
Note that the ClearType fix is in the .NET 4 version of the DLL, not in the 3.5sp1 version. That's due to it using ClearType enhancements that came about only in .NET 4. One interesting thing to note here is that we do actually have two different DLLs now, so you can have your .NET 4 project and use a version compiled specifically for .NET 4.

Download the WPF Ribbon

Samples

This release includes several samples, including a nice MVVM sample.
RibbonWindow Wordpad Sample
This sample illustrates a Ribbon control hosted within a RibbonWindow that emulates the Wordpad appearance.
RibbonWindow MVVM Sample
This sample illustrates a Ribbon control hosted within a RibbonWindow that is completely populated from a view-model collection.

RibbonBrowser Wordpad sample
This sample illustrates a Ribbon control hosted within a browser window that emulates the Wordpad appearance.

RibbonBrowser MVVM sample
This sample illustrates a Ribbon control hosted within a browser window that is completely populated from a view model collection.

martedì 18 gennaio 2011

ToolKit

Se volete un toolkit per WPF, gratuito e affidabile lo potete trovare al sequente indirizzo : http://wpf.codeplex.com/

lunedì 10 gennaio 2011

Dispatcher

 Il Dispatcher è un oggetto presente sia in WPF che in Silverlight ed è responsabile della coda di operazioni che si susseguono durate il ciclo di vita di un'operazione. Il comportamento è simile alla message pump di Win32: un ciclo continuo attende che una nuova DispatcherOperation venga accodata e la esegue appena possibile. L'unica differenza risiede nella possibilità di dare una priorità nell'operazione così da garantire per esempio che le operazioni di rendering abbiano la precedenza su quelle di input o su quelle di background.
In WPF attraverso la proprietà Hooks del Dispatcher si hanno a disposizione un po' di eventi per monitorare (occhio che si strozza parecchio il processamento delle richieste) l'accondamento delle operazioni. Per prima cosa si può notare quante operazioni vengono eseguite senza che ce ne accorgiamo. Il thread infatti è uno solo e la fluidità che si può percepire nell'interazione con i controlli o nelle animazioni è solo data dal fatto che la macchina processa le operazioni velocemente, ma ecco perché non appena si esegue qualcosa di più dispendioso per la CPU o si resta in attesa di una risposta, si causa il blocco dell'intera applicazione.
Nel thread del Dispatcher infatti ci finiscono tutti gli input da tastiera, mouse e altri device (il touch in futuro), arrivano i messaggi dalle altre finestre Win32, vengono gestiti gli handler degli eventi dei controlli e quindi eseguito il proprio codice, viene effettuato il rendering di tutti gli elementi presenti nell'applicazione e vengono inoltre gestite tutte le animazioni. Un semplice oggetto con Storyboard associata che varia per esempio nel tempo la larghezza dell'elemento, fa sì che nel dispatcher vengano accodate tantissime operazioni, fino anche 50/60 al secondo, pari a quanti frame al secondo si intende renderizzare. E' interessante poi notare attraverso l'evento OperationAborted come, nel caso la CPU non è in grado di soddisfare tale rate o per rallentamenti dovuti ad operazioni intermedie fra un frame e l'altro, il motore abortistica alcuni di questi frame, sacrificando la fluidità, ma mantenendo l'obiettivo: raggiungere un valore in un intervallo ben preciso. Questa è una delle principali differenze che Silverlight ha con Flash dove quest'ultimo lavora ad un frame rate fisso preindicato, ignorando il carico di lavoro che la macchina ha.
In WPF inoltre si ha a disposizione il signor DispatcherFrame che permette di aprire una finestra sul medesimo thread, bloccando però il creatore della finestra. Questa tecnica viene utilizzata per le finestre modali dove chiamando ShowDialog il chiamante del metodo attende che la finestra venga chiusa, mentre tutte le operazioni accodate nel Dispatcher vengano comunque processate al suo interno, mantenendo attive le animazioni della finestra chiamante e della finestra modale, e reagendo agli input dell'utente. Il fatto che sulla finestra chiamante non si possa interagire è solo un impedimento di Windows, ma tecnicamente è possibile accodare operazioni che intervengano su di essa.
Il DispatcherFrame può essere usato anche per un uso alternativo. Per capirci su un click di pulsante si può fare:
DispatcherFrame frame = new DispatcherFrame(true); 

Debug.WriteLine("Creazione DispatcherFrame"); 

// Timer che scatta dopo 3 secondi 
System.Timers.Timer timer = new System.Timers.Timer(3000); 
timer.AutoReset = false; 
timer.Elapsed += delegate 
{ 
    Debug.WriteLine("Frame in termine"); 
    frame.Continue = false; 
}; 
timer.Start(); 

// Avvio il frame e attendo che finisca 
Dispatcher.PushFrame(frame); 

Debug.WriteLine("Frame uscito");
Se eseguito, nonostate il timer scatti dopo tre secondi dando tutto il tempo di processare l'istruzione "Frame uscito", l'output è:
Creazione DispatcherFrame
Frame in termine
Frame uscito