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...
Full WPF Archive