WPF: Xceed AvalonDock (it-it)
Introduzione
In questo articolo faremo una carrellata di esempi di utilizzo della Xceed AvalonDock, ossia l’AvalonDock ufficiale per progetti WPF.
Il sito di riferimento è https://avalondock.codeplex.com
L’ultima versione la 2.0 è del giugno 2013.
Vediamo prima di tutto cosa è l’AvalonDock.
AvalonDock è un pannello contenitore che permette di spostare (ancorare) le finestre in diversi punti dello schermo per adattarlo alla propria risoluzione e assieme al NavigationPane permette di scrivere applicazioni Business accattivanti e facili da usare anche per il neofita. Per intenderci Visual Studio è fatto con l’AvalonDock.
Implementazione
Scarichiamo da questo link i codici di esempio: http://avalondock.codeplex.com/SourceControl/latest#
Una volta scaricato e scompattato il file avalondock-102592.zip, vediamo che abbiamo tre versioni: la 1.2, la 1.3 e l’ultima, la 2.0.
Andiamo a vedere la versione 1.2: apriamo la Solution in Visual Studio 2015. Faremo l’aggiornamento unidirezionale.
C’è il progetto della libreria e il progetto di esempio. Mettiamo come progetto di avvio quello di test, premiamo F5 e vediamo questa schermata:
Giochiamoci un po' trascinando le varie finestre:
Andando nel Menù File possiamo anche cambiare i colori:
Proviamo ora la versione 1.3.
Nella cartella 1.3 apriamo la solution AvalonDock.sln, sempre con Visual Studio 2015.
La solution è composta da 20 progetti. Dobbiamo impostare come progetto d’avvio AvalonDock.DemoApp.
Giochiamoci un po':
Anche qua possiamo cambiare colori e tema. Quello che segue è il tema Visual Studio 2010.
Infine vediamo la versione 2.0.
La versione 2.0 la troviamo hostata cnhe su https://github.com/VirusFree/AvalonDock
Apriamo la Solution Xceed.Wpf.AvalonDock.sln
Vediamo che il progetto è composta da 8 progetti.
Impostiamo come progetto d’avvio AvalonDock.TestApp.
Avviamo ora l’applicazione.
Vediamo anche qua di giocarci un po'.
Possiamo anche salvare il Layout in modo da non dover spostare le finestre a ogni avvio della nostra applicazione.
Un esempio facile da usare e funzionante è un progetto hostato su Github. Il link è https://github.com/feliperomero3/XceedAvalonDockSandbox
Scarichiamo il progetto e apriamo la Solution con Visual Studio 2015.
Vediamo che c’è un solo progetto con già referenziata la libreria Xceed.AvalonDock versione 2.
Avviamo il progetto ed ecco la schermata:
Anche qua ci giochiamo un po':
Libreria Origin
Vediamo infine un’altra libreria. È hostata su Github. Si chiama Origin ed è sviluppata da Grant Colley.
Il link è questo: https://github.com/grantcolley/origin
Vediamo prima come è strutturato il progetto. Scarichiamo il file zippato origin-master.zip e lo scompattiamo.
Apriamo ora in Visual Studio la Solution DevelopmentInProgress.Origin.sln
Vediamo che ci sono tre progetti.
Mettiamo come progetto di avvio DevelopmentInProgress.Origin
Ricompiliamo il progetto e lanciamo l’applicazione:
Proviamo come al solito a giocarci:
Vediamo adesso come sono composti i tre progetti:
- DevelopmentInProgress.Origin: è il Framework contenente la Shell; possiamo creare moduli da aggiungere al Framework.
- DevelopmentInProgress.ExampleModule: questo modulo contiene esempi per il modulo Origin. Da qui possiamo imparare come funziona e come creare nuovi moduli. Una volta creati nuovi moduli, ricordarsi di cambiare I nomi in ModuleCatalog.xaml nella cartella Configuration di DevelopmentInProgress.Origin.
- DevelopmentInProgress.ModuleTemplate: è un Template, un modello da usare come base per la scrittura dei moduli.
Vediamo ora come creare un modulo.
Passo 1 - creare una libreria di classi per il modulo
1. Aprire la solution DevelopmentInProgress.Origin.sln in Visual Studio e aggiungere un nuovo progetto libreria di classi.
2. nel nuovo progetto aggiungere un riferimento al progetto DevelopmentInProgress.Origin.
Nel mio caso è: C:\...\origin-master\Binaries\DevelopmentInProgress.Origin.exe
3. aggiungere i riferimenti a:
◦PresentationCore.dll
◦PresentationFramework.dll
◦WindowsBase.dll
◦System.XAML.dll
4. aggiungere riferimenti alle seguenti librerie prism nella cartella ThirdParty:
◦Microsoft.practices.Prism.dll
◦Microsoft.practices.Prism.UnityExtensions.dll
◦Microsoft.practices.Unity.dll
Ecco come viene l’Esplora Risorse:
5. nella pagina delle proprietà del progetto Vai alla scheda di compilazione e modifica il percorso di output di compilazione nella stessa posizione come l'output di compilazione per il progetto di DevelopmentInProgress.Origin per esempio..\.\.\Binaries\
6. creare le seguenti tre cartelle nel progetto:
- View
- ViewModel
- Images
7. aggiungere due immagini. png nella cartella immagini. Uno sarà per il modulo e uno sarà per il documento. Queste immagini saranno visualizzate sul pannello di navigazione. Non dimenticare di impostare la proprietà BuildAction come risorsa.
Passo 2 – Crea le tue View, ViewModel e Modulo
1. nella cartella ViewModel creare una nuova classe chiamata NewDocumentViewModel.cs e scrivere il seguente codice:
using DevelopmentInProgress.Origin.Context;
using DevelopmentInProgress.Origin.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DevelopmentInProgress.ModuleTemplate.ViewModel
{
public class NewDocumentViewModel : DocumentViewModel
{
public NewDocumentViewModel(ViewModelContext viewModelContext)
: base(viewModelContext)
{
}
protected override ProcessAsyncResult OnPublishedAsync(object data)
{
return base.OnPublishedAsync(data);
}
protected override void OnPublishedCompleted(ProcessAsyncResult processAsyncResult)
{
base.OnPublishedCompleted(processAsyncResult);
}
protected override ProcessAsyncResult SaveDocumentAsync()
{
return base.SaveDocumentAsync();
}
}
}
2. Nella cartella View creare un nuovo UserControl WPF chiamato NewDocumentView.xaml e scriverci il seguente codice:
using DevelopmentInProgress.ModuleTemplate.ViewModel;
using DevelopmentInProgress.Origin.Context;
using DevelopmentInProgress.Origin.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DevelopmentInProgress.ModuleTemplate.View
{
/// <summary>
/// Logica di interazione per NewDocumentView.xaml
/// </summary>
public partial class NewDocumentView : DocumentViewBase
{
public NewDocumentView(IViewContext viewContext, NewDocumentViewModel newDocumentViewModel)
: base(viewContext, newDocumentViewModel, Module.ModuleName)
{
InitializeComponent();
DataContext = newDocumentViewModel;
}
}
}
Mentre lo XAML:
<view:DocumentViewBase x:Class="DevelopmentInProgress.ModuleTemplate.View.NewDocumentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:view="clr-namespace:DevelopmentInProgress.Origin.View;assembly=DevelopmentInProgress.Origin"
mc:Ignorable="d">
<Grid>
</Grid>
</view:DocumentViewBase>
3. Creare una classe chiamata Module.cs
Inserire questo codice:
using DevelopmentInProgress.ModuleTemplate.View;
using DevelopmentInProgress.ModuleTemplate.ViewModel;
using DevelopmentInProgress.Origin.Module;
using DevelopmentInProgress.Origin.Navigation;
using Microsoft.Practices.Prism.Logging;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DevelopmentInProgress.ModuleTemplate
{
public class Module : ModuleBase
{
public const string ModuleName = "Module Template";
public Module(IUnityContainer container, ModuleNavigator moduleNavigator, ILoggerFacade logger)
: base(container, moduleNavigator, logger)
{
}
public override void Initialize()
{
Container.RegisterType<Object, NewDocumentView>(typeof(NewDocumentView).Name);
Container.RegisterType<NewDocumentViewModel>(typeof(NewDocumentViewModel).Name);
var moduleSettings = new ModuleSettings();
moduleSettings.ModuleName = ModuleName;
moduleSettings.ModuleImagePath = @"/DevelopmentInProgress.ModuleTemplate;component/Images/ModuleTemplate.png";
var moduleGroup = new ModuleGroup();
moduleGroup.ModuleGroupName = "Module Template";
var newDocument = new ModuleGroupItem();
newDocument.ModuleGroupItemName = "New Document";
newDocument.TargetView = typeof(NewDocumentView).Name;
newDocument.TargetViewTitle = "New Document";
newDocument.ModuleGroupItemImagePath = @"/DevelopmentInProgress.ModuleTemplate;component/Images/NewDocument.png";
moduleGroup.ModuleGroupItems.Add(newDocument);
moduleSettings.ModuleGroups.Add(moduleGroup);
ModuleNavigator.AddModuleNavigation(moduleSettings);
Logger.Log("Initialize DevelopmentInProgress.ModuleTemplate Complete", Category.Info, Priority.None);
}
}
}
Infine, nel progetto DevelopmentInProgress.Origin c’è una cartella chiamata Configuration.
All’interno c’è un file chiamato ModuleCatalog.xaml: apriamolo e aggiungiamo questo codice:
<prism:ModuleInfo Ref="Module Template"
ModuleName="DevelopmentInProgress.ModuleTemplate"
ModuleType="DevelopmentInProgress.ModuleTemplate.Module,DevelopmentInProgress.ModuleTemplate"
InitializationMode="WhenAvailable"/>
Conclusioni
Abbiamo visto alcuni esempi di uso del AvalonDock. Ognuno può personalizzare il tutto, nei vari template, nelle librerie, negli UserControl etc etc. Tra l’altro I moduli potrebbero essere pure in un database e quindi caricati a runtime.