Esistono diverse strategie con cui è possibile realizzare un Help che realmente possa essere utile. Il .Net Framework, per le applicazioni “Windows Form” mette a disposizione una serie di strumenti che è possibile utilizzare a proprio piacimento per la realizzazione di una documentazione in linea, tema la cui importanza non va assolutamente sottovalutata perché un buon software è sempre corredato da una buona documentazione.

Oggi voglio mostrarvi come ho realizzato una guida in linea sensibile al contesto (Context Sensitive Help) all’interno di una Client Application realizzata con il .Net Framework.

* Tralasciando la spiegazione di come si realizza una guida in linea (Microsoft Compiled HTML Help), argomento su cui ci sarebbe molto da discutere, questo post vuole spiegare come integrare un file di questo tipo all’interno di un’applicazione Windows Form.

Partiamo dai presupposti, un oggetto di tipo System.Windows.Forms.Form espone una serie di proprietà, tra queste troviamo anche un evento chiamato HelpRequested che lo sviluppatore può eventualmente implementare, a riguardo la documentazione parla chiaro:

L’evento HelpRequested viene solitamente generato quando l’utente preme il tasto F1 o fa clic su un pulsante della Guida sensibile al contesto.

L’implementazione risulta molto semplice, nei form in cui vogliamo fornire aiuto possiamo decidere di invocare un metodo che possa, in base al contesto, darci informazioni utili reperite direttamente dal file di guida.

Inoltre è necessario sapere che un file di guida “Microsoft Compiled HTML Help” contiene al suo interno una serie di file html compressi, questi file vengono associati ad un identificatore univoco definito in un file Header (scritto in C) e che riporta il riferimento ad ogni link, questo file viene utilizzato in fase di compilazione della guida e serve propri per indicizzare i contenuti della nostra documentazione per poterla successivamente interrogare utilizzando un TopicId.

Ora, all’interno dei Windows Form sono si presenti delle proprietà per la gestione dell’Help ma non sono quelle di cui noi abbiamo bisogno (in pratica il .Net Framework mette a disposizione una serie di Tooltip che vengono visualizzati per dare aiuto). Supponiamo di aver definito nel nostro file di guida un argomento chiamato “Come effettuare il login”, a questo è stato assegnato l’indice 1000, come fare per ottenere un focus su questo argomento nella guida in linea direttamente dall’applicazione? La soluzione che ho applicato è molto semplice, ogni controllo, all’interno di un applicazione Windows espone una proprietà chiamata Tag che è di tipo Object, lo scopo di questa è proprio memorizzare informazioni aggiuntive nel nostro form come per esempio oggetti, stringhe o quanto ci possa tornare più utile, io ho deciso di inserire in questo campo il TopicId che dovrebbe essere richiamato se l’utente chiede aiuto durante l’esecuzione dell’applicazione, successivamente ho realizzato un oggetto che ho chiamato HelpProvider il cui compito è attivare l’help in linea su un determinato form:

internal sealed class HelpProvider 
{
	//Nome del file guida
	private const string ChmFileName = "Docs.chm";
	private Form _form;

	internal Form Form 
	{ 
		get 
		{ 
			return (this._form); 
		} 
	}

	private HelpProvider()
	{
		this._form = null;
	}

	internal HelpProvider(Form form)
	{

		HelpNamespace = Path.Combine(
			Environment.CurrentDirectory,
			ChmFileName);
		
		_form = form;
		_form.HelpRequested += new HelpEventHandler(OnHelpRequestedAction);
	}

	internal void TryAsk()
	{
		Control ctrl = null;
		if ((this._form.ActiveControl != null) 
			&& 
		    (!IsNull(this._form.ActiveControl)))
			ctrl = this._form.ActiveControl;
		else
			ctrl = _form;

		if (ctrl.Tag == null)
		{
			Program.ShowWarning("Unable to retrive help information for this argument.");
			return;
		}

		Help.ShowHelp(ctrl, HelpNamespace, HelpNavigator.TopicId, ctrl.Tag as string);
	}

	/// <summary>
	/// Event Handled when an help request is execute by pressing F1
	/// </summary>
	/// <param name="sender" />
	/// <param name="hlpevent" />
	private void OnHelpRequestedAction(object sender, HelpEventArgs hlpevent)
	{
		this.TryAsk();

		hlpevent.Handled = true;
	}
}

Il funzionamento è molto semplice, questo oggetto riceve in ingresso un Form su cui imposta l’evento  HelpRequested per poter successivamente intercettare le richieste da parte dell’utente, resta in attesa, quando una richiesta viene inoltrata, viene scatenato l’evento OnHelpRequestedAction in cui viene invocato il metodo TryAsk.

Questo metodo effettua diverse operazioni, prima di tutto legge il valore del Tag del controllo che gli viene passato, se questo valore è diverso da NULL,  invoco un metodo, ShowHelp, che fornisce la classe Help del .Net Framework in cui passo:

  • ctrl: Controllo che chiede Aiuto (un form o un qualsiasi controllo presente nella maschera corrente)
  • HelpNamespace: nome del file di guida da invocare per la documentazione
  • HelpNavigator.TopicId: modalità di lettura della documentazione,cioè, quando apro la guida, cosa devo fare esattamente, se cercare per argomento, per indice etc.
  • ctrl.Tag: identificativo dell’argomento di cui vogliamo le informazioni.

L’HelpProvider, può essere facilmente utilizzato in questo modo: nel form in cui vogliamo rendere attiva la funzionalità di help, dichiariamo una variabile privata di tipo HelpProvider che andiamo ad inizializzare nel costruttore del nostro Form come nell’esempio che segue:

public class MyWindowsApp : System.Windows.Forms.Form {
	private HelpProvider _helpProvider;
	
	public MyWindowsApp() {
		_helpProvider = new HelpProvider(this);
	}
}

Con queste poche righe di codice abbiamo attivato un help in linea completo e funzionante!

Ricordate che per funzionare è necessario che i controlli e / o direttamente i form per cui devono essere disponibili informazioni, devono avere la variabile Tag valorizzata con un certo indice equivalente ad un TopicId del nostro file “Windows Compiled HTML Help”, in caso contrario l’help non viene mostrato.