WPF
L’AOP ormai sta diventando un paradigma di programmazione sempre più diffuso specialmente nel mondo .NET dove strumenti come PostSharp, DotSpect (Compile-time static injection) e Spring.NET, Castle Windsor, Enterprise Library Policy Injection Application Block (Dynamic Proxy) rendono sempre più semplice la gestione dei “cross-cutting concerns” che provengono dal mondo Object-Oriented. Personalmente sono stato sempre un entusiasta di PostSharp e in questo post vorrei citare un paio di aspect che ho sempre valutato positivamente nella gestione di codice “vicino” alla UI, specialmente nel mondo Windows Forms e WPF.
Il primo aspect ha a che vedere con il DataBinding. Sappiamo tutti come implementare l’interfaccia INotifyPropertyChanged...
Le Reactive Extensions (Rx) del framework .NET sono un set di API dedicate a ciò che nella letteratura prende il nome di “reactive programming”. Rx nasce dalla distinzione di due scenari:
pull: un programma agisce estraendo dati dall’ambiente in modo interattivo (es. un’iterazione su una sequenza di dati prelevati dall’ambiente).
push: un programma reagisce ai dati che l’ambiente “spinge” verso di esso (es. un event-handler è un esempio di reazione in uno scenario push)
Data questa distinzione, Rx si basa sulla dualità tra il pattern Iterator e il pattern Observer. In breve, il pattern Observer...
Il controllo DataGrid di WPF 4.0 permette di ottenere “gratis” l’esportazione dei dati associati alla griglia in diversi formati tra cui plain text, CSV e HTML. Tale funzionalità è esposta semplicemente tramite l’invocazione del comando Copy sul controllo, che trasferisce nella Clipboard i dati contenuti nelle ...
Quando si realizza un’interfaccia grafica per l’inserimento dati, è sempre buona prassi prevedere una prima "validazione" dell'input utente. Una tecnica molto semplice per raggiungere tale obiettivo potrebbe basarsi sull’idea di filtrare l’input in modo da non permettere l’inserimento di caratteri non validi. Nel caso della TextBox, in particolare, si potrebbe pensare di estendere il controllo affinché il filtraggio avvenga a fronte di un matching con un generica espressione regolare… una RegexTextBox dunque :).
public class RegexTextBox : System.Windows.Controls.TextBox{ public string Pattern { get; set; } public RegexTextBox() { CommandBinding pasteCommandBinding = new CommandBinding(ApplicationCommands.Paste); pasteCommandBinding.CanExecute += delegate(object sender, CanExecuteRoutedEventArgs e) { e.Handled...
Una funzionalità fondamentale per text-editor/reader è l’evidenziazione programmatica di testo, magari utilizzando stili di formattazione diversi. In questo post vorrei mostrare una possibile implementazione di tale funzionalità utilizzando il controllo RichTextBox di WPF. Immaginando un approccio top-down, potremmo partire da un metodo HilightText(…), il cui compito sia proprio quello di evidenziare del testo all’interno di una RichTextBox.
public void HilightText(string pattern)
{
List<TextRange> ranges = GetMatchingTextRanges(pattern);
foreach (TextRange textRange in ranges) HilightTextRange(textRange, Brushes.Black, Brushes.Yellow);
}
L’idea è quella di applicare un background giallo ed un foreground nero a tutti gli intervalli di testo (TextRange) che soddisfano...
Durante lo sviluppo di applicazioni WPF di una certa “pesantezza”, può essere utile ricorrere a Splash Screen aggiornabili in tempo reale che notifichino all’utente lo stato di avanzamento del caricamento dei vari moduli, ad esempio tramite elementi di testo piuttosto che barre di progresso. A volte, infatti, può non essere sufficiente una semplice immagine impostabile tramite la Build Action "SplashScreen" di Visual Studio.
In questo post vorrei quindi mostrare una possibile implementazione di uno Splash Screen aggiornabile in tempo reale usando il pattern MVVM.
Per semplificare, supponiamo di posizionare nel Main la pesantissima sequenza di caricamento della nostra applicazione:
public static class Program
{...
In applicazioni WPF di una certa complessità è molto facile trovarsi in situazioni in cui è utile sfruttare classi base per i controlli (es. UserControl e Window). In architetture MVVM, ad esempio, è possibile far ereditare i vari controlli da classi base generiche. Tuttavia, l’ implementazione dell’ereditarietà generica in WPF talvolta non è proprio immediata, soprattutto perché non sempre gli errori di build sono esplicativi.
In questo semplicissimo esempio di MVVM viene mostrato come si può specificare la classe base generica di una Window direttamente nello XAML.
Partiamo dalla Window:
public partial class CustomersWindow : WindowBase<CustomersViewModel>
{
public CustomersWindow() : base(new CustomersViewModel())...
Analizzando diverse soluzioni WPF che sfruttano l’architettura M-V-VM, mi è saltata all’occhio una strategia di implementazione dell’interfaccia ICommand semplice e potente a mio modo di vedere. Andiamo direttamente al codice: public class GenericCommand<T> : ICommand { public Predicate<T> CanExecuteDelegate { get; set; } public Action<T> ExecuteDelegate { get; set; } public bool CanExecute(object parameter) { if (CanExecuteDelegate...
La possibilità di creare Window di forma irregolare costituisce a mio modo di vedere uno dei più divertenti nonché semplici vantaggi di WPF. In genere, ogni tecnica di realizzazione di Window dalla forma completamente personalizzata si basa sulla valorizzazione preliminare di tre proprietà: Window.AllowsTransparency = True Window.WindowStyle = None Window.Background = Transparent In questo modo siamo subito svincolati sia dalla forma rettangolare standard della nostra Window, che dalla barra standard del titolo. Si aprono quindi diverse possibilità di sviluppo. E’ possibile ad...
Spesso in ambiente desktop può essere utile salvare degli screenshot relativi alla UI della nostra applicazione: in alcuni scenari ad esempio, oltre ai soliti log e trace, è molto comodo avere automaticamente lo screenshot dell’UI al momento dell’errore, magari come allegato di una email di report. Una comune soluzione in Windows Forms è quella che sfrutta GDI+ tramite il metodo Graphics.CopyFromScreen(…) . In questo post vorrei mostrare come anche in WPF è possibile approfittare della stessa tecnica con il minimo sforzo: in particolare, nell’ helper class che segue sono presenti degli overload del metodo SaveScreenShot(…) per salvare...
In un’ applicazione WPF, per default la classe Application mantiene viva l’applicazione stessa finché almeno una finestra è ancora aperta. Se si vuole cambiare questo comportamento, è possibile utilizzare la proprietà Application.ShutdownMode direttamente dal markup XAML: ( ATTENZIONE: se si istanzia l’oggetto Application a mano, è obbligatorio impostare la proprietà ShutdownMode prima di invocare il metodo Run() ) I valori ammissibili per tale proprietà sono: OnLastWindowClose (default): l’applicazione WPF rimane in vita fintantoché esiste almeno una Window attiva....
Per chi sviluppa utilizzando il pattern M-V-VM l’interfaccia ICommand costituisce la base per costruire un’infrastruttura che permetta alla View di invocare comandi applicativi direttamente nel ViewModel. L’interfaccia mette a disposizione tre semplici membri: due metodi Execute(...), CanExecute(...) ed un evento CanExecuteChanged. E’ facile immaginare come in progetti di una certa consistenza sia necessario costruirsi delle implementazioni spesso particolari dell’interfaccia ICommand, cosa che da una parte implica tanta buona volontà, dall’altra ripaga quando si dormono sonni tranquilli pensando ad una View completamente svincolata dalla logica applicativa. In genere un’ utile implementazione di ICommand poggia sull’ intercettazione dell’evento CanExecuteChanged...
Più volte nello sviluppo Silverlight/WPF mi sono imbattuto nella necessità di utilizzare i file di risorsa (.resx) e devo dire che le prime volte mi sono trovato un po’ in difficoltà dal momento che non riuscivo a capire per quale arcano i miei binding dichiarativi nel codice XAML verso le mie risorse non funzionassero affatto. Andiamo per ordine: supponendo di definire un file di risorsa in questo modo ... ... in fase di design Visual Studio notifica uno “strano” errore, indipendentemente dal fatto che...
Qualche giorno fa mi sono imbattutto in una simpatica applicazione Windows Forms che permette di disegnare su una lavangna virtuale il posizionamento in campo di due squadre di calcio. Un'applicazione per allenatori insomma :D. In breve, il funzionamento è semplicemente basato sull'aggiunta e sullo spostamento di pedine (rosse o blu) su un campo di calcio virtuale con eventuale possibilità di ingrandirne/rimpicciolirne le dimensioni. Guardando il sorgente ho osservato come l’intera applicazione fosse stata concepita e sviluppata "alla Windows Forms" con l'intera logica piazzata all'interno di ciascun event handler dei vari elementi dell'UI. Ho...
In generale, una semplice soluzione per realizzare un ColorPicker si basa sull'utilizzo di un' immagine che rappresenta lo spettro dei colori, come la seguente: Dopodiché, per rilevare il colore selezionato al passaggio del Mouse abbiamo ovviamente bisogno di conoscere le coordinate del cursore su tale immagine. In WPF questa operazione è veramente molto semplice sfruttando la classe CroppedBitmap. Se definissimo una BitmapSource come Source della nostra Image WPF, ecco come potremmo implementare un semplice metodo per individuare il colore RGB corrispondente alle coordinate del...
Stavo cercando un controllo PropertyGrid per WPF ed in men che non si dica ecco che esce fuori su codeplex:
WPF PropertyGrid Control
Forte!!!
Come si può notare è molto simile al property editor di Expression Blend, anche se lo scopo del progetto è:
The purpose of this project not to clone existing Microsoft Expression Blend property editor or Visual Studio 2008 property pad for "Cider" WPF designer but rather introducing a scalable and comprehensive control ready to be used in different types of applications Credo sarà interessante dare un'occhiata al sorgente :D
P.S.: Se qualcuno di voi già lo conosce/utilizza mi piacerebbe avere qualche...
In questi giorni sto studiando a fondo il pattern M-V-VM ((Data)Model-View-ViewModel), visto che quando fu introdotto per la prima volta (ormai 3 anni fa) non lo valutai affatto positivamente poiché ero convinto che avrebbe "sporcato" troppo il pattern MVC, creando confusione sia tra gli sviluppatori che tra gli architects. Questo pattern fu coniato nel 2005 da John Gossman mentre WPF vedeva la luce (Avalon). In uno dei suoi post a riguardo, Gossman lo definì nella seguente maniera: Model/View/ViewModel is a variation of Model/View/Controller (MVC) that is tailored for modern UI development platforms where the...
In questi giorni mi sono scontrato (letteralmente) con le varie opzioni di configurazione e deploy di una applicazione WPF. Mi sembra utile appuntarmi qui le varie issues apprese, sperando che mi correggiate qualora dovessi scrivere qualche castroneria :).Visual Studio 2008 fornisce diversi tool per garantire un rapido e non troppo doloroso deploy di una applicazione WPF: XCopy, Microsoft Windows Installer, ClickOnce ed anche via connessioni Remote Desktop. La tecnologia di deploy dipende chiaramente dal tipo di applicazione WPF: Applicazioni stand-alone Applicazioni XBAP (XAML Browser Applications) Pagine XAML 'Browser-Hosted' Per lo sviluppo Web, il punto di partenza sicuramente...
Un grande passo in avanti che WPF offre oltre alle note features built-in relative al packaging (XPS, OpenXML, formati custom) ed alla security, è il supporto alla visualizzazione ed alla fruizione dei contenuti. Ad oggi, WPF divide i documenti in due grandi categorie in base all'utilizzo a cui sono destinati: "fixed documents" e "flow documents". Fixed documents: sono utilizzati in applicazioni WYSIWYG, ovvero indipendenti dalla risoluzione dello schermo o dal dispositivo di stampa. Parliamo quindi di scenari in cui è fondamentale la fedeltà nei confronti del design della pagina originale (es. applicazioni word processing, form layout etc.), in quanto...
Volendo presentare dei dati in formato tabellare con uno stile grafico maggiormente accattivante, ho voluto provare ad utilizzare l' hosting di un controllo WPF in una Windows Forms già esistente. Ora, già sapevo che in realtà la rappresentazione dei dati in formato griglia in WPF viene implementata tramite una personalizzazione della proprietà View del controllo ListView. Quello che invece non mi aspettavo era che nel layout "GridView mode" di un ListView mancasse di default una feature "scontata" come il sorting tramite click sull' header delle colonne (abituale sia in Windows Forms che in ASP.NET).Ho trovato dunque questo articolo su MSDN, How to: Sort a GridView Column When a Header Is Clicked, dove si mostra...
Vorrei segnalare il blog di Derek Mehlhorn, dedicato totalmente allo sviluppo delle Annotations per i controlli WPF FlowDocumentPageViewer, FlowDocumentScrollViewer, FlowDocumentReader e DocumentViewer. Ci sono degli ottimi post su come entrare 'praticamente' nel merito della tecnologia e capirne i reali vantaggi. Molto interessante ;)!!!
Oggi, con una certa soddisfazione , ho sperimentato sulla mia pelle l'utilizzo di IValueConverter, un' interfaccia molto utile (contenuta nel namespace System.Windows.Data di presentationframework.dll) che rende possibile il binding tra proprietà di tipo diverso nel mondo WPF.Nello specifico, all'interno della mia applicazione ho riscontrato il bisogno di un metodo veloce per effettuare il binding tra alcune proprietà di oggetti custom (ordini precisamente... che fantasia !!!) e proprietà di presentazione di una ListBox. Grazie all' implementazione dell'interfaccia IValueConverter, per ciascun ListBoxItem in binding ho potuto quindi realizzare la conversione del valore della proprietà Priority del mio oggetto Order nel valore della proprietà Foreground del corrispondente TextBlock (che visualizza il nome dell'ordine). Ecco l'esempio: <Window ... xmlns:mydata="clr-namespace:MyNamespace">
<Window.Resources>
...