XAML - Guida rapida

XAML è l'acronimo di Extensible Application Markup Language. È un linguaggio semplice e dichiarativo basato su XML.

  • In XAML è molto facile creare, inizializzare e impostare le proprietà di un oggetto con relazioni gerarchiche.

  • Viene utilizzato principalmente per la progettazione di GUI.

  • Può essere utilizzato anche per altri scopi, ad esempio per dichiarare il flusso di lavoro in Workflow Foundation.

XAML può essere utilizzato in diverse piattaforme come WPF (Windows Presentation Foundation), Silverlight, Mobile Development e Windows Store App. Può essere utilizzato in diverse versioni di .Net framework e CLR (Common Language Runtime).

Come funziona XAML

XAML è un file declarative linguaggio nel senso che definisce il WHAT e HOWvuoi fare. Il processore XAML è responsabile perHOWparte per scoprirlo. Diamo uno sguardo al seguente schema. Riassume il lato XAML delle cose:

La figura illustra le seguenti azioni:

  • Il file XAML viene interpretato da un processore XAML specifico della piattaforma.

  • Il processore XAML trasforma il codice XAML in codice interno che descrive l'elemento dell'interfaccia utente.

  • Il codice interno e il codice C # sono collegati tra loro tramite definizioni di classi parziali e quindi il compilatore .NET compila l'app.

Vantaggi di XAML

Uno dei problemi di vecchia data che tutti noi dobbiamo affrontare con la progettazione della GUI può essere risolto utilizzando XAML. Può essere utilizzato per progettare elementi dell'interfaccia utente nelle applicazioni Windows Form.

Nei precedenti framework GUI, non c'era una vera separazione tra l'aspetto di un'applicazione e il modo in cui si comporta. Sia la GUI che il suo comportamento sono stati creati nello stesso linguaggio, ad esempio C # o VB.net, il che richiederebbe uno sforzo maggiore da parte dello sviluppatore per implementare sia l'interfaccia utente che il comportamento ad essa associato.

Con XAML è molto facile separare il comportamento dal codice di progettazione. Pertanto, il programmatore XAML e il designer possono lavorare in parallelo. I codici XAML sono molto facili da leggere e da capire.

Microsoft fornisce due importanti strumenti per XAML:

  • Visual Studio
  • Miscela di espressioni

Attualmente, entrambi gli strumenti possono creare XAML, ma il fatto è che Visual Studio è usato maggiormente dagli sviluppatori mentre Expression Blend è ancora usato più spesso dai progettisti.

Microsoft fornisce una versione gratuita di Visual Studio che può essere scaricata da https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx

Note- Per questo tutorial, utilizzeremo principalmente progetti WPF e l'app di Windows Store. Ma la versione gratuita di Visual Studio non supporta l'app di Windows Store. Quindi, a tale scopo, avrai bisogno di una versione con licenza di Visual Studio.

Installazione

Segui i passaggi indicati di seguito per installare Visual Studio sul tuo sistema -

  • Dopo aver scaricato i file, esegui il programma di installazione. Verrà visualizzata la seguente finestra di dialogo.

  • Fare clic sul pulsante Installa e inizierà il processo di installazione.

  • Una volta completato con successo il processo di installazione, vedrai la seguente schermata.

  • Chiudi questa finestra di dialogo e riavvia il computer se necessario.

  • Ora apri Visual Studio dal menu Start che mostrerà la seguente finestra di dialogo. Ci vorrà del tempo per la prima volta, solo per la preparazione.

Una volta fatto tutto, vedrai la finestra principale di Visual Studio.

Primo passo verso l'implementazione

Cominciamo con una semplice implementazione. Segui i passaggi indicati di seguito:

  • Fare clic su File → Nuovo → opzione di menu Progetto.

  • Verrà visualizzata la seguente finestra di dialogo:

  • In modelli, seleziona Visual C # e seleziona Applicazione WPF. Assegna un nome al progetto e fai clic sul pulsante OK.

  • Nel file mainwindow.xaml, i seguenti tag XAML vengono scritti per impostazione predefinita. Capirai tutti questi tag più avanti in questo tutorial.

<Window x:Class = "FirstStepDemo.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:FirstStepDemo" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
         
   </Grid> 
</Window>

Per impostazione predefinita, una griglia è impostata come primo elemento dopo la pagina.

Aggiungiamo un pulsante e un blocco di testo sotto l'elemento Grid. Questo è chiamatoobject element syntax, una parentesi angolare sinistra seguita dal nome di ciò che si desidera istanziare, ad esempio un pulsante, quindi definire una proprietà di contenuto. La stringa assegnata al Contenuto verrà visualizzata sul pulsante. Ora imposta l'altezza e la larghezza del pulsante rispettivamente su 30 e 50. Allo stesso modo inizializza le proprietà del blocco di testo.

Ora guarda la finestra di progettazione. Vedrai un pulsante. Ora premi F5 per eseguire questo codice XAML.

<Window x:Class = "FirstStepDemo.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:local = "clr-namespace:FirstStepDemo" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Content = "First Button" Height = "30" Width = "80"/> 
      <TextBlock Text = "Congratulations you have successfully build your first app" 
         Height = "30" Margin = "162,180,122,109"/> 
   </Grid> 
	
</Window>

Quando compili ed esegui il codice sopra, vedrai la seguente finestra.

Congratulazioni! Hai progettato il tuo primo pulsante.

Le applicazioni XAML possono essere sviluppate anche su Mac. Su Mac, XAML può essere utilizzato come applicazioni iOS e Android. Per configurare l'ambiente su Mac, vai su www.xamarin.com . Fare clic su Prodotti e selezionare la piattaforma Xamarin. Scarica Xamarin Studio e installalo. Ti permetterà di sviluppare applicazioni per le varie piattaforme.

XAML: sintassi C #

In questo capitolo imparerai la sintassi e le regole XAML di base per scrivere applicazioni XAML. Diamo un'occhiata a un semplice file XAML.

<Window x:Class = "Resources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
         
   </Grid> 
</Window>

Come puoi vedere nel file XAML sopra, ci sono diversi tipi di tag ed elementi. La tabella seguente descrive brevemente tutti gli elementi.

Suor n Elementi e descrizione
1

<Window

È l'elemento oggetto di apertura o il contenitore della radice.

2

x:Class="Resources.MainWindow"

È la dichiarazione di classe parziale che collega il markup al codice di classe parziale dietro definito in esso.

3

xmlns

Mappa lo spazio dei nomi XAML predefinito per il client / framework WPF

4

xmlns:x

Spazio dei nomi XAML per il linguaggio XAML che lo associa al prefisso x:

5

>

Fine dell'elemento oggetto della radice.

6

<Grid>

</Grid>

Tag di avvio e chiusura di un oggetto griglia vuoto.

7

</Window>

Chiusura dell'elemento oggetto

Regole di sintassi per l'elemento oggetto

Le regole di sintassi per XAML sono quasi simili a XML. Se dai un'occhiata a un documento XAML, noterai che in realtà si tratta di un file XML valido. Tuttavia, un file XML non può essere un file XAML valido. È perché in XML, il valore degli attributi deve essere una stringa, mentre in XAML può essere un oggetto diverso noto come sintassi dell'elemento Property.

  • La sintassi di un elemento Object inizia con una parentesi angolare sinistra (<) seguita dal nome dell'oggetto, ad esempio Button.

  • Definisci alcune proprietà e attributi di quell'elemento oggetto.

  • L'elemento Object deve essere chiuso da una barra (/) seguita immediatamente da una parentesi angolare retta (>).

Esempio di oggetto semplice senza elemento figlio -

<Button/>

Esempio di elemento oggetto con alcuni attributi -

<Button Content = "Click Me" Height = "30" Width = "60"/>

Esempio di una sintassi alternativa per definire le proprietà (sintassi dell'elemento proprietà) -

<Button> 
   <Button.Content>Click Me</Button.Content> 
   <Button.Height>30</Button.Height> 
   <Button.Width>60</Button.Width> 
</Button>

Esempio di oggetto con elemento figlio: StackPanel contiene Textblock come elemento figlio

<StackPanel Orientation = "Horizontal"> 
   <TextBlock Text = "Hello"/> 
</StackPanel>

Puoi usare XAML per creare, inizializzare e impostare le proprietà degli oggetti. Le stesse attività possono essere eseguite anche utilizzando il codice di programmazione.

XAML è solo un altro modo semplice e facile per progettare elementi dell'interfaccia utente. Con XAML, spetta a te decidere se dichiarare oggetti in XAML o dichiararli utilizzando il codice.

Facciamo un semplice esempio per dimostrare come scrivere in XAML:

<Window x:Class = "XAMLVsCode.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <StackPanel> 
      <TextBlock Text = "Welcome to XAML Tutorial" Height = "20" Width = "200" Margin = "5"/>
      <Button Content = "Ok" Height = "20" Width = "60" Margin = "5"/> 
   </StackPanel> 
	
</Window>

In questo esempio, abbiamo creato un pannello della pila con un pulsante e un blocco di testo e definito alcune delle proprietà del pulsante e del blocco di testo come Altezza, Larghezza e Margine. Quando il codice precedente viene compilato ed eseguito, produrrà il seguente output:

Ora guarda lo stesso codice scritto in C #.

using System; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls;  

namespace XAMLVsCode { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent();  
         
         // Create the StackPanel 
         StackPanel stackPanel = new StackPanel();
         this.Content = stackPanel; 
			
         // Create the TextBlock 
         TextBlock textBlock = new TextBlock(); 
         textBlock.Text = "Welcome to XAML Tutorial"; 
         textBlock.Height = 20;
         textBlock.Width = 200; 
         textBlock.Margin = new Thickness(5); 
         stackPanel.Children.Add(textBlock);  
			
         // Create the Button 
         Button button = new Button(); 
         button.Content = "OK"; 
         button.Height = 20; 
         button.Width = 50; 
         button.Margin = new Thickness(20); 
         stackPanel.Children.Add(button); 
      } 
   }
}

Quando il codice precedente viene compilato ed eseguito, produrrà il seguente output. Tieni presente che è esattamente uguale all'output del codice XAML.

Ora puoi vedere quanto sia semplice usare e comprendere XAML.

In questo capitolo, scriveremo lo stesso esempio in VB.Net in modo che anche coloro che hanno familiarità con VB.Net possano comprendere i vantaggi di XAML.

Diamo nuovamente un'occhiata allo stesso esempio scritto in XAML:

<Window x:Class = "XAMLVsCode.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <TextBlock Text = "Welcome to XAML Tutorial with VB.net" Height = "20" Width = "220" Margin = "5"/> 
      <Button Content = "Ok" Height = "20" Width = "60" Margin = "5"/> 
   </StackPanel> 
	
</Window>

In questo esempio, abbiamo creato un pannello a pila con un pulsante e un blocco di testo e definito alcune delle proprietà del pulsante e del blocco di testo come Altezza, Larghezza e Margine. Quando il codice precedente viene compilato ed eseguito, produrrà il seguente output:

Ora guarda lo stesso codice scritto in VB.Net -

Public Class MainWindow
   Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) 
      Dim panel As New StackPanel() 
      panel.Orientation = Orientation.Vertical 
      Me.Content = panel 
      Dim txtInput As New TextBlock 
		
      txtInput.Text = "Welcome to XAML Tutorial with VB.net" 
      txtInput.Width = 220 
      txtInput.Height = 20 
      txtInput.Margin = New Thickness(5) 
		
      panel.Children.Add(txtInput)  
      Dim btn As New Button()
		
      btn.Content = "Ok" 
      btn.Width = 60 
      btn.Height = 20 
      btn.Margin = New Thickness(5) 
		
      panel.Children.Add(btn)
   End Sub 
End Class

Quando il codice precedente viene compilato ed eseguito, l'output è esattamente lo stesso dell'output del codice XAML.

È ora possibile visualizzare quanto sia semplice lavorare con XAML rispetto a VB.Net.

Nell'esempio precedente, abbiamo visto che ciò che possiamo fare in XAML può essere fatto anche in altri linguaggi procedurali come C # e VB.Net.

Diamo un'occhiata a un altro esempio in cui useremo sia XAML che VB.Net. Progetteremo una GUI in XAML e il comportamento verrà implementato in VB.Net.

In questo esempio, un pulsante viene aggiunto alla finestra principale. Quando l'utente fa clic su questo pulsante, viene visualizzato un messaggio nella finestra del messaggio. Ecco il codice in XAML in cui viene dichiarato un oggetto Button con alcune proprietà.

<Window x:Class="MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Name = "btn" HorizontalAlignment = "Center" Width = "60" Height = "30" Content = "Click Me" /> 
   </Grid> 
	
</Window>

In VB.Net, viene implementato l'evento clic del pulsante (comportamento). Questo evento visualizza il messaggio nella casella dei messaggi.

Public Class MainWindow
   Private Sub btn_Click(sender As Object, e As RoutedEventArgs) Handles btn.Click 
      MessageBox.Show("Button is Clicked") 
   End Sub 
End Class

Quando il codice sopra viene compilato ed eseguito, verrà visualizzata la seguente schermata:

Ora fai clic sul pulsante sopra che dice "Cliccami". Verrà visualizzato il seguente messaggio:

Questo capitolo descriverà alcuni degli elementi costitutivi di base e importanti delle applicazioni XAML. Spiegherà come

  • per creare e inizializzare un oggetto,
  • un oggetto può essere modificato facilmente utilizzando risorse, stili e modelli,
  • per rendere interattivo un oggetto utilizzando trasformazioni e animazioni.

Oggetti

XAML è un linguaggio tipicamente dichiarativo che può creare e istanziare oggetti. È un altro modo per descrivere gli oggetti basati su XML, ovvero quali oggetti devono essere creati e come dovrebbero essere inizializzati prima dell'esecuzione di un programma. Gli oggetti possono essere

  • Contenitori (pannello Stack, pannello Dock)
  • Elementi / controlli dell'interfaccia utente (pulsante, casella di testo, ecc.)
  • Dizionari di risorse

Risorse

Le risorse sono normalmente definizioni collegate a qualche oggetto che prevedi di utilizzare più spesso di una volta. È la capacità di memorizzare i dati localmente per i controlli o per la finestra corrente o globalmente per le intere applicazioni.

Stili

Il framework XAML offre diverse strategie per personalizzare e personalizzare l'aspetto di un'applicazione. Gli stili ci danno la flessibilità di impostare alcune proprietà di un oggetto e riutilizzare queste impostazioni specifiche su più oggetti per un aspetto coerente.

  • Negli stili, puoi impostare solo le proprietà esistenti di un oggetto come Altezza, Larghezza, Dimensione carattere, ecc.
  • È possibile specificare solo il comportamento predefinito di un controllo.
  • È possibile aggiungere più proprietà in uno stile.

Nel primo diagramma, puoi vedere le stesse proprietà di altezza e larghezza impostate per tutti e tre i pulsanti separatamente; ma nel secondo diagramma, puoi vedere che l'altezza e la larghezza che sono uguali per tutti i pulsanti vengono aggiunte a uno stile e quindi questo stile è associato a tutti i pulsanti.

Modelli

Un modello descrive l'aspetto generale e l'aspetto visivo di un controllo. Ad ogni controllo è associato un modello predefinito che conferisce l'aspetto a quel controllo. In XAML puoi creare facilmente i tuoi modelli quando vuoi personalizzare il comportamento visivo e l'aspetto visivo di un controllo.

Nella schermata seguente, ci sono due pulsanti, uno è con il modello e l'altro è il pulsante predefinito.

Ora, quando passi il mouse sul pulsante, cambia anche il colore come mostrato di seguito.

Con i modelli, puoi accedere a più parti di un controllo rispetto agli stili. È possibile specificare sia il comportamento esistente che quello nuovo di un controllo.

Animazioni e trasformazioni

Le animazioni e le trasformazioni all'interno di Windows Runtime possono migliorare la tua applicazione XAML creando interattività e movimento. Puoi integrare facilmente l'aspetto interattivo nella tua applicazione XAML usando le animazioni dalla libreria di animazioni di Windows Runtime. Vengono utilizzate le animazioni

  • per migliorare l'interfaccia utente o per renderla più attraente.
  • per attirare l'attenzione dell'utente su un cambiamento.

Nello screenshot seguente, puoi vedere un quadrato:

Quando passi il mouse su questo quadrato, si estenderà in tutte le direzioni come mostrato di seguito.

Il framework dell'interfaccia utente XAML offre un'ampia libreria di controlli che supporta lo sviluppo dell'interfaccia utente per Windows. Alcuni di loro hanno una rappresentazione visiva come Button, Textbox, TextBlock, ecc .; mentre altri controlli vengono utilizzati come contenitori per altri controlli o contenuti, ad esempio immagini. Tutti i controlli XAML vengono ereditati daSystem.Windows.Controls.Control.

La gerarchia di ereditarietà completa dei controlli è la seguente:

Ecco l'elenco dei controlli di cui discuteremo uno per uno in questo capitolo.

Sr.No. Controlli e descrizione
1 Pulsante

Un controllo che risponde all'input dell'utente.

2 Calendario

Rappresenta un controllo che consente a un utente di selezionare una data utilizzando una visualizzazione del calendario visuale.

3 CheckBox

Un controllo che un utente può selezionare o deselezionare.

4 Combo box

Un elenco a discesa di elementi da cui un utente può selezionare.

5 Menù contestuale

Ottiene o imposta l'elemento del menu di scelta rapida che deve essere visualizzato ogni volta che il menu di scelta rapida viene richiesto tramite un'interfaccia utente (UI) dall'interno di questo elemento.

6 DataGrid

Rappresenta un controllo che visualizza i dati in una griglia personalizzabile.

7 Date picker

Un controllo che consente a un utente di selezionare una data.

8 Dialoghi

Un'applicazione può anche mostrare all'utente finestre aggiuntive per raccogliere o visualizzare informazioni importanti.

9 Vista a griglia

Controllo che presenta una raccolta di elementi in righe e colonne che possono scorrere orizzontalmente.

10 Immagine

Un controllo che presenta un'immagine.

11 ListBox

Un controllo che presenta un elenco in linea di elementi da cui l'utente può selezionare.

12 Menu

Rappresenta un controllo del menu di Windows che consente di organizzare gerarchicamente gli elementi associati ai comandi e ai gestori di eventi.

13 PasswordBox

Un controllo per l'immissione delle password.

14 Apparire

Visualizza il contenuto sopra il contenuto esistente, entro i limiti della finestra dell'applicazione.

15 Barra di avanzamento

Un controllo che indica lo stato di avanzamento visualizzando una barra.

16 ProgressRing

Un controllo che indica un progresso indeterminato visualizzando un anello.

17 RadioButton

Un controllo che consente a un utente di selezionare una singola opzione da un gruppo di opzioni.

18 RichEditBox

Un controllo che consente a un utente di modificare documenti di testo RTF con contenuto come testo formattato, collegamenti ipertestuali e immagini.

19 ScrollViewer

Un controllo contenitore che consente all'utente di eseguire la panoramica e lo zoom del contenuto.

20 Casella di ricerca

Un controllo che consente a un utente di immettere query di ricerca.

21 Slider

Un controllo che consente all'utente di selezionare da un intervallo di valori spostando un controllo Thumb lungo una traccia.

22 TextBlock

Un controllo che visualizza il testo.

23 TimePicker

Un controllo che consente a un utente di impostare un valore temporale.

24 Interruttore

Un pulsante che può essere commutato tra 2 stati.

25 ToolTip

Una finestra a comparsa che visualizza le informazioni per un elemento.

26 Finestra

La finestra principale che fornisce l'opzione di riduzione / ingrandimento, barra del titolo, bordo e pulsante di chiusura.

In questo capitolo discuteremo tutti questi controlli con l'implementazione.

La disposizione dei controlli è molto importante e fondamentale per l'usabilità dell'applicazione. È necessario organizzare un gruppo di elementi della GUI nell'applicazione. Ci sono alcuni punti importanti da considerare durante la selezione dei pannelli di layout;

  • Posizioni degli elementi figlio.
  • Dimensioni degli elementi figlio.
  • Stratificazione di elementi figlio sovrapposti uno sopra l'altro.

La disposizione dei pixel fissa dei controlli non funziona quando un'applicazione è stata utilizzata con risoluzioni dello schermo diverse. XAML fornisce un ricco set di pannelli di layout incorporati per organizzare gli elementi della GUI in modo appropriato. Alcuni dei pannelli di layout più comunemente usati e popolari sono i seguenti:

Suor n Pannelli e descrizione
1 StackPanel

Il pannello Stack è un pannello di layout semplice e utile in XAML. In un pannello a pila, gli elementi secondari possono essere disposti su una singola riga, orizzontalmente o verticalmente, in base alla proprietà di orientamento.

2 WrapPanel

In WrapPanel, gli elementi figlio vengono posizionati in un ordine sequenziale da sinistra a destra o dall'alto verso il basso in base alla proprietà di orientamento.

3 DockPanel

DockPanel definisce un'area per disporre gli elementi figlio l'uno rispetto all'altro, orizzontalmente o verticalmente. Con DockPanel, puoi facilmente agganciare elementi figlio in alto, in basso, a destra, a sinistra e al centro con la proprietà Dock.

4 CanvasPanel

Il pannello Canvas è il pannello di layout di base in cui gli elementi figlio possono essere posizionati in modo esplicito utilizzando coordinate relative al Canvas su qualsiasi lato come sinistra, destra, superiore e inferiore.

5 GridPanel

Un pannello Griglia fornisce un'area flessibile composta da righe e colonne. In una griglia, gli elementi figlio possono essere disposti in una forma tabulare.

Il concetto generale di eventi in XAML è simile agli eventi in altri linguaggi di programmazione popolari come .NET e C ++. In XAML, tutti i controlli espongono alcuni eventi in modo che possano essere sottoscritti per scopi specifici.

Ogni volta che si verifica un evento, l'applicazione riceverà una notifica e il programma può reagire ad essi, ad esempio, i pulsanti di chiusura vengono utilizzati per chiudere una finestra di dialogo.

Esistono molti tipi di eventi che possono essere sottoscritti per comportamenti diversi di un'applicazione in base ai requisiti di tale applicazione, ma gli eventi più comunemente utilizzati sono quelli relativi a mouse e tastiera come,

  • Click
  • MouseDown
  • MouseEnter
  • MouseLeave
  • MouseUp
  • KeyDown
  • KeyUp

In questo capitolo, utilizzeremo alcuni degli eventi di base e più comunemente usati per capire come un evento di un controllo specifico possa essere collegato al codice dietro il quale verrà implementato il comportamento a seconda di ciò che l'utente vuole fare quando un evento specifico si verifica.

Diamo un'occhiata a un semplice esempio di un evento clic su un pulsante. Di seguito è riportata l'implementazione XAML per il controllo Button che viene creato e inizializzato con alcune proprietà e un evento Click (Click = "OnClick").

<Window x:Class = "XAMLEventHandling.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button x:Name = "button1" Content = "Click" Click = "OnClick" 
         Width = "150" Height = "30" HorizontalAlignment = "Center" /> 
   </Grid>
   
</Window>

Ogni volta che si fa clic su questo pulsante, verrà attivato un file OnClicked è possibile aggiungere qualsiasi tipo di comportamento come risposta al clic. Diamo un'occhiata all'implementazione dell'evento OnClick che mostrerà un messaggio quando si fa clic su questo pulsante.

using System; 
using System.Windows; 
using System.Windows.Controls;  

namespace XAMLEventHandling {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void OnClick(object sender, RoutedEventArgs e) { 
         MessageBox.Show("Button is clicked!"); 
      } 
   }
}

Quando compili ed esegui il codice sopra, produrrà il seguente output:

Quando si fa clic sul pulsante, verrà generato l'evento clic (OnClick) e verrà visualizzato il seguente messaggio.

Ora diamo un'occhiata a un esempio un po 'complesso in cui vengono gestiti più eventi.

Esempio

L'esempio seguente contiene una casella di testo con ContextMenu che manipola il testo all'interno della casella di testo.

Il codice XAML seguente crea un TextBox, un ContextMenu e MenuItems con alcune proprietà ed eventi come Checked, Unchecked e Click.

<Window x:Class = "XAMLContextMenu.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <TextBox Name = "textBox1" TextWrapping = "Wrap" Margin = "10" Grid.Row = "7"> 
         Hi, this is XAML tutorial. 
         <TextBox.ContextMenu>
         
            <ContextMenu>
               <MenuItem Header = "_Bold" IsCheckable = "True" 
                  Checked = "Bold_Checked" Unchecked = "Bold_Unchecked" /> 
               <MenuItem Header = "_Italic" IsCheckable = "True" 
                  Checked = "Italic_Checked" Unchecked = "Italic_Unchecked" /> 
               <Separator /> 
               <MenuItem Header = "Increase Font Size" Click = "IncreaseFont_Click" />
               <MenuItem Header = "_Decrease Font Size" Click = "DecreaseFont_Click" /> 
            </ContextMenu> 
				
         </TextBox.ContextMenu>
      </TextBox>
   </Grid> 
	
</Window>

Ecco l'implementazione in C # per i diversi eventi che verranno attivati ​​ogni volta che una voce di menu viene selezionata, deselezionata o cliccata.

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;  

namespace XAMLContextMenu { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary>
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void Bold_Checked(object sender, RoutedEventArgs e) { 
         textBox1.FontWeight = FontWeights.Bold; 
      }
      private void Bold_Unchecked(object sender, RoutedEventArgs e) { 
         textBox1.FontWeight = FontWeights.Normal; 
      }
      private void Italic_Checked(object sender, RoutedEventArgs e) { 
         textBox1.FontStyle = FontStyles.Italic; 
      }
      private void Italic_Unchecked(object sender, RoutedEventArgs e) { 
         textBox1.FontStyle = FontStyles.Normal; 
      }
      private void IncreaseFont_Click(object sender, RoutedEventArgs e) { 
         if (textBox1.FontSize < 18) { 
            textBox1.FontSize += 2; 
         } 
      }
      private void DecreaseFont_Click(object sender, RoutedEventArgs e) { 
         if (textBox1.FontSize > 10) { 
            textBox1.FontSize -= 2; 
         } 
      }
   }
}

Quando compili ed esegui il codice sopra, produrrà il seguente output:

Ti consigliamo di eseguire il codice di esempio sopra e sperimentare altri eventi.

Eventi

Sr.No. Controlli e descrizione
1

Checked

Viene eseguito quando viene selezionato un ToggleButton. (Ereditato da ToggleButton)

2

Click

Si verifica quando si fa clic su un controllo pulsante. (Ereditato da ButtonBase)

3

ContextMenuClosing

Si verifica appena prima della chiusura di qualsiasi menu di scelta rapida sull'elemento. (Ereditato da FrameworkElement.)

4

ContextMenuOpening

Si verifica quando viene aperto un menu di scelta rapida sull'elemento. (Ereditato da FrameworkElement.)

5

DataContextChanged

Si verifica quando il valore della proprietà FrameworkElement.DataContext cambia. (Ereditato da FrameworkElement)

6

DragEnter

Si verifica quando il sistema di input segnala un evento di trascinamento sottostante con questo elemento come destinazione. (Ereditato da UIElement).

7

DragLeave

Si verifica quando il sistema di input segnala un evento di trascinamento sottostante con questo elemento come origine. (Ereditato da UIElement)

8

DragOver

Si verifica quando il sistema di input segnala un evento di trascinamento sottostante con questo elemento come potenziale destinazione di rilascio. (Ereditato da UIElement)

9

DragStarting

Si verifica quando viene avviata un'operazione di trascinamento. (Ereditato da UIElement)

10

DropCompleted

Si verifica al termine di un'operazione di trascinamento. (Ereditato da UIElement)

11

DropDownClosed

Si verifica quando si chiude la parte a discesa di ComboBox.

12

DropDownOpened

Si verifica quando si apre la parte a discesa di ComboBox.

13

GotFocus

Si verifica quando un oggetto UIElement riceve lo stato attivo. (Ereditato da UIElement)

14

Holding

Si verifica quando si verifica un'interazione Hold altrimenti non gestita sull'area di hit test di questo elemento. (Ereditato da UIElement)

15

Intermediate

Viene eseguito quando lo stato di un ToggleButton passa allo stato indeterminato. (Ereditato da ToggleButton)

16

IsEnabledChanged

Si verifica quando la proprietà IsEnabled cambia. (Ereditato da Control)

17

KeyDown

Si verifica quando viene premuto un tasto della tastiera mentre UIElement è attivo. (Ereditato da UIElement)

18

KeyUp

Si verifica quando un tasto della tastiera viene rilasciato mentre UIElement è attivo. (Ereditato da UIElement)

19

LostFocus

Si verifica quando un oggetto UIElement perde lo stato attivo. (Ereditato da UIElement)

20

ManipulationCompleted

Si verifica quando una manipolazione su UIElement è completa. (Ereditato da UIElement)

21

ManipulationDelta

Si verifica quando il dispositivo di input cambia posizione durante una manipolazione. (Ereditato da UIElement)

22

ManipulationInertiaStarting

Si verifica quando il dispositivo di input perde il contatto con l'oggetto UIElement durante una manipolazione e inizia l'inerzia. (Ereditato da UIElement)

23

ManipulationStarted

Si verifica quando un dispositivo di input inizia una manipolazione in UIElement. (Ereditato da UIElement)

24

ManipulationStarting

Si verifica quando il processore di manipolazione viene creato per la prima volta. (Ereditato da UIElement)

25

SelectionChanged

Si verifica quando la selezione del testo è cambiata.

26

SizeChanged

Si verifica quando la proprietà ActualHeight o ActualWidth cambia il valore in un FrameworkElement. (Ereditato da FrameworkElement)

27

Unchecked

Si verifica quando un ToggleButton è deselezionato. (Ereditato da ToggleButton)

28

ValueChanged

Si verifica quando il valore dell'intervallo cambia. (Ereditato da RangeBase)

Il data binding è un meccanismo nelle applicazioni XAML che fornisce un modo semplice e facile per le app di Windows Runtime usando classi parziali per visualizzare e interagire con i dati. La gestione dei dati è completamente separata dal modo in cui i dati vengono visualizzati in questo meccanismo.

Il data binding consente il flusso di dati tra gli elementi dell'interfaccia utente e l'oggetto dati sull'interfaccia utente. Quando viene stabilita un'associazione e i dati o il modello di business cambiano, rifletterà automaticamente gli aggiornamenti agli elementi dell'interfaccia utente e viceversa. È anche possibile associare, non a un'origine dati standard, ma piuttosto a un altro elemento della pagina. Il data binding può essere di due tipi:

  • Associazione dati unidirezionale
  • Associazione dati bidirezionale

Associazione dati unidirezionale

Nell'associazione unidirezionale, i dati vengono associati dalla relativa origine (ovvero l'oggetto che contiene i dati) alla sua destinazione (ovvero l'oggetto che visualizza i dati).

Diamo un'occhiata a un semplice esempio di associazione dati unidirezionale. Il codice XAML seguente crea quattro blocchi di testo con alcune proprietà.

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> 
            <TextBlock Text = "Name: " Margin = "10" Width = "100" /> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Name}" />
         </StackPanel> 
		
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> 
            <TextBlock Text = "Title: " Margin = "10" Width = "100" /> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> 
         </StackPanel>
      </StackPanel>
   </Grid> 
	
</Window>

Le proprietà di testo di due blocchi di testo sono impostate su "Nome" e "Titolo" staticamente, mentre gli altri due blocchi di testo Le proprietà di testo sono vincolate a "Nome" e "Titolo" che sono variabili di classe della classe Employee mostrata di seguito.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace DataBindingOneWay {
   public class Employee {
      public string Name { get; set; } 
      public string Title { get; set; }  
		
      public static Employee GetEmployee() {
         var emp = new Employee() { 
            Name = "Ali Ahmed", Title = "Developer" 
         }; 
         return emp; 
      }
   }
}

In questa classe abbiamo solo due variabili, Name e Titlee un metodo statico in cui viene inizializzato l'oggetto Employee che restituirà quell'oggetto dipendente. Quindi ci stiamo associando a una proprietà, Nome e Titolo, ma non abbiamo selezionato a quale oggetto appartiene quella proprietà. Il modo più semplice è assegnare un oggetto a DataContext le cui proprietà stiamo associando nel seguente codice C #:

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace DataBindingOneWay { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      } 
   }
}

Eseguiamo questa applicazione e puoi vedere immediatamente nella nostra MainWindow che abbiamo associato con successo il nome e il titolo di quell'oggetto Employee.

Associazione dati bidirezionale

Nell'associazione a due vie, l'utente può modificare i dati tramite l'interfaccia utente e aggiornare i dati nell'origine. Se la sorgente cambia mentre l'utente sta guardando la vista, potresti voler aggiornare la vista.

Esempio

Diamo un'occhiata al seguente esempio in cui vengono create una casella combinata con tre elementi della casella combinata e una casella di testo con alcune proprietà. In questo esempio, non abbiamo alcuna origine dati standard, ma gli elementi dell'interfaccia utente sono associati ad altri elementi dell'interfaccia utente.

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel>
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100"> 
         <ComboBoxItem Content = "Green" /> 
         <ComboBoxItem Content = "Yellow" IsSelected = "True" /> 
         <ComboBoxItem Content = "Orange" /> 
      </ComboBox>
		
      <TextBox  Name = "textBox" Margin = "50" 
         Width = "100" Height = "23" VerticalAlignment = "Top" 
         Text  = "{Binding ElementName = comboBox, Path = SelectedItem.Content, 
         Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox>
   </StackPanel> 
	
</Window>

Quando compili ed esegui il codice precedente, produrrà il seguente output. Quando l'utente seleziona un elemento dalla casella combinata, il testo della casella di testo e il colore di sfondo verranno aggiornati di conseguenza.

Allo stesso modo, quando l'utente digita un nome di colore valido nella casella di testo, verranno aggiornati anche la casella combinata e il colore di sfondo della casella di testo.

Nelle applicazioni XAML, le estensioni di markup sono un metodo / tecnica per ottenere un valore che non è né un oggetto XAML specifico né un tipo primitivo. Le estensioni di markup possono essere definite aprendo e chiudendo le parentesi graffe e all'interno di tali parentesi graffe viene definito l'ambito dell'estensione di markup.

Il data binding e le risorse statiche sono estensioni di markup. Esistono alcune estensioni di markup XAML predefinite inSystem.xaml che può essere utilizzato.

Diamo un'occhiata a un semplice esempio in cui StaticResources viene utilizzata l'estensione di markup che è un'estensione di markup XAML predefinita.

Il codice XAML seguente crea due blocchi di testo con alcune proprietà e il loro primo piano è definito in Window.Resources.

<Window x:Class = "XAMLStaticResourcesMarkupExtension.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
   </Window.Resources> 
	
   <Grid> 
      <StackPanel Orientation = "Vertical"> 
         <TextBlock Foreground = "{StaticResource myBrush}" Text = "First Name" 
            Width = "100" Margin = "10" /> 
         <TextBlock Foreground = "{StaticResource myBrush}" Text = "Last Name" 
            Width = "100" Margin = "10" /> 
      </StackPanel> 
   </Grid> 
	
</Window>

In Window.Resources, Puoi vedere x:Key viene utilizzato che identifica in modo univoco gli elementi creati e referenziati in un dizionario definito XAML per identificare una risorsa in un dizionario risorse.

Quando compili ed esegui il codice precedente, verrà prodotto il seguente MainWindow. Puoi vedere i due blocchi di testo con il colore di primo piano blu.

In XAML, le estensioni di markup personalizzate possono essere definite anche ereditando la classe MarkupExtension e sovrascrivendo il metodo ProvideValue, che è un metodo astratto nella classe MarkupExtension.

Diamo un'occhiata a un semplice esempio di estensione di markup personalizzata.

<Window x:Class = "XAMLMarkupExtension.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:my = "clr-namespace:XAMLMarkupExtension" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <Button Content = "{my:MyMarkupExtension FirstStr = Markup, SecondStr = Extension}" 
         Width = "200" Height = "20" /> 
   </Grid> 
	
</Window>

Nel codice XAML precedente, viene creato un pulsante con alcune proprietà e per il valore del contenuto, un'estensione di markup personalizzata (my:MyMarkupExtension) è stato utilizzato con due valori "Markup" e "Extension" assegnati rispettivamente a FirstStr e SecondStr.

In realtà, MyMarkupExtensionè una classe che deriva da MarkupExtensioncome mostrato di seguito nell'implementazione C #. Questa classe contiene due variabili stringa, FirstStr e SecondStr, che vengono concatenate e restituiscono quella stringa dal metodo ProvideValue al contenuto di un pulsante.

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.Markup; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace XAMLMarkupExtension { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
      public MainWindow() { 
         InitializeComponent(); 
      } 
   }
   public class MyMarkupExtension : MarkupExtension { 
      public MyMarkupExtension() { } 
      public String FirstStr { get; set; } 
      public String SecondStr { get; set; }  
		
      public override object ProvideValue(IServiceProvider serviceProvider) { 
        return FirstStr + " " + SecondStr; 
      } 
   }
}

Eseguiamo questa applicazione e puoi vedere immediatamente nella nostra MainWindow che "estensione di markup" è stata utilizzata con successo come contenuto del pulsante.

Una proprietà di dipendenza è un tipo specifico di proprietà in cui il valore è seguito da un sistema di proprietà appassionato che fa anche parte dell'app Windows Runtime. Una classe che definisce una proprietà di dipendenza deve essere ereditata dalla classe DependencyObject.

Molte delle classi di controllo dell'interfaccia utente usate in XAML derivano dalla classe DependencyObject e supportano le proprietà di dipendenza. Il codice XAML seguente crea un pulsante con alcune proprietà.

<Window x:Class = "XAMLDependencyProperty.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLDependencyProperty"
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <Button Height = "40" Width = "175" Margin = "10" Content = "Dependency Property">
         <Button.Style>
            <Style TargetType = "{x:Type Button}">
               <Style.Triggers> 
                  <Trigger Property = "IsMouseOver" Value = "True">
                     <Setter Property = "Foreground" Value = "Red" />
                  </Trigger>
               </Style.Triggers>
            </Style>
         </Button.Style>
      </Button>
   </Grid>
   
</Window>

L'estensione di markup x: Type in XAML ha una funzionalità simile come typeof () in C #. Viene utilizzato quando vengono specificati attributi che accettano il tipo di oggetto come <Style TargetType = "{x: Type Button}">

Quando compili ed esegui il codice precedente, verrà prodotto il seguente MainWindow. Quando il mouse è sopra il pulsante, cambierà il colore di primo piano del pulsante. Quando il mouse lascia il pulsante, tornerà al suo colore originale.

La principale differenza tra le proprietà di dipendenza e altre proprietà CLR sono:

  • Le proprietà CLR possono leggere / scrivere direttamente dal membro privato di una classe utilizzando getter e setter. In caso di proprietà di dipendenza, non viene memorizzato in un oggetto locale.

  • Le proprietà di dipendenza sono archiviate in un dizionario di coppie chiave / valore fornito dalla classe DependencyObject.

  • Inoltre consente di risparmiare molta memoria perché memorizza la proprietà quando viene modificata.

  • Può essere associato anche in XAML.

In .NET framework, è possibile definire anche proprietà di dipendenza personalizzate. Di seguito sono riportati i passaggi per definire la proprietà di dipendenza personalizzata in C #.

  • Dichiara e registra la tua proprietà di dipendenza con il registro delle chiamate di sistema.

  • Fornisci il setter e il getter per la proprietà.

  • Definire un gestore statico per gestire le modifiche che si verificano a livello globale.

  • Definisci un gestore di istanze per gestire le modifiche che si verificano in quella particolare istanza.

Di seguito è riportato il codice in C # per la proprietà di dipendenza definita per impostare la proprietà SetText del controllo utente.

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 WpfApplication3 {
   /// <summary> 
      /// Interaction logic for UserControl1.xaml 
   /// </summary> 
	
   public partial class UserControl1 : UserControl {
      public UserControl1() {
         InitializeComponent();
      }
      public static readonly DependencyProperty
         SetTextProperty = DependencyProperty.Register("SetText", typeof(string), 
         typeof(UserControl1), new PropertyMetadata("", 
         new PropertyChangedCallback(OnSetTextChanged)));
      public string SetText {
         get {return(string) GetValue(SetTextProperty); }
         set {SetValue(SetTextProperty, value);}
      }
      private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
         UserControl1 UserControl1Control = d as UserControl1;
         UserControl1Control.OnSetTextChanged(e);
      }
      private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) {
         tbTest.Text = e.NewValue.ToString();
      }
   }
}

Ecco il file XAML in cui TextBlock è definito come controllo utente e la proprietà Text gli verrà assegnata dalla proprietà di dipendenza SetText.

Il codice XAML seguente crea un controllo utente con l'inizializzazione della relativa proprietà di dipendenza SetText e alcune altre proprietà.

<Window x:Class = "WpfApplication3.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:views = "clr-namespace:WpfApplication3" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <views:UserControl1 SetText = "Hellow World" />
   </Grid>
	
</Window>

Eseguiamo questa applicazione e puoi vedere immediatamente nella nostra MainWindow che la proprietà di dipendenza per il controllo utente è stata utilizzata con successo come testo.

Le risorse sono normalmente definizioni collegate a qualche oggetto che prevedi di utilizzare più spesso di una volta. Ha la capacità di memorizzare i dati localmente per i controlli o per la finestra corrente o globalmente per le intere applicazioni.

Definire un oggetto come risorsa ci permette di accedervi da un altro posto. Quindi, consente la riutilizzabilità. Le risorse sono definite nei dizionari delle risorse e qualsiasi oggetto può essere definito come una risorsa in modo efficace rendendolo una risorsa condivisibile. Una chiave univoca viene specificata per la risorsa XAML e con tale chiave è possibile fare riferimento a essa usando un'estensione di markup StaticResource.

Diamo nuovamente un'occhiata a un semplice esempio in cui vengono creati due blocchi di testo con alcune proprietà e il loro colore di primo piano è definito in Window.Resources.

<Window x:Class = "XAMLResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
   </Window.Resources>  
	
   <StackPanel Orientation = "Vertical"> 
      <TextBlock Foreground = "{StaticResource myBrush}" 
         Text = "First Name" Width = "100" Margin = "10" /> 
      <TextBlock Foreground = "{StaticResource myBrush}" 
         Text = "Last Name" Width = "100" Margin = "10" /> 
   </StackPanel> 
	
</Window>

Quando il codice precedente viene compilato ed eseguito, produrrà la seguente MainWindow. Puoi vedere due blocchi di testo con il colore di primo piano blu. Il vantaggio della risorsa è che se sono presenti più blocchi di testo e si desidera modificare il colore di sfondo, sarà sufficiente modificarlo nel dizionario delle risorse.

Ambito delle risorse

Le risorse vengono definite nei dizionari delle risorse, ma esistono numerosi posti in cui è possibile definire un dizionario delle risorse. Nell'esempio precedente, un dizionario delle risorse è definito a livello di finestra / pagina. In quale dizionario viene definita una risorsa limita immediatamente l'ambito di quella risorsa. Quindi l'ambito, cioè dove puoi usare la risorsa, dipende da dove l'hai definita.

  • Definisci la risorsa nel dizionario delle risorse di una griglia ed è accessibile solo da quella griglia e dai suoi elementi figlio.

  • Definiscilo su una finestra / pagina ed è accessibile da tutti gli elementi su quella finestra / pagina.

  • La radice dell'app può essere trovata nel dizionario delle risorse App.xaml. È la radice della nostra applicazione, quindi le risorse qui definite sono limitate all'applicazione completa.

Per quanto riguarda l'ambito della risorsa, i più spesso sono il livello dell'applicazione, il livello della pagina e un livello di elemento specifico come Grid, StackPanel, ecc.

Dizionari di risorse

I dizionari di risorse nelle app XAML implicano dizionari di risorse in file separati. È seguito in quasi tutte le app XAML. La definizione di risorse in file separati può avere i seguenti vantaggi:

  • Separazione tra la definizione delle risorse nel dizionario delle risorse e il codice relativo all'interfaccia utente.

  • La definizione di tutte le risorse in un file separato come App.xaml le renderebbe disponibili nell'App.

Quindi, come possiamo definire le nostre risorse in un dizionario risorse in un file separato? Bene, è molto semplice, basta aggiungere un nuovo dizionario delle risorse tramite Visual Studio seguendo i seguenti passaggi:

  • Nella tua soluzione, aggiungi una nuova cartella e assegnagli un nome ResourceDictionaries.

  • Fare clic con il tasto destro su questa cartella e selezionare Dizionario delle risorse dalla voce di sottomenu Aggiungi e denominarla DictionaryWithBrush.xaml

Diamo uno sguardo alla stessa applicazione; solo il dizionario risorse è ora definito a livello di app.

Ecco il codice XAML per MainWindow.xaml.

<Window x:Class = "XAMLResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel Orientation = "Vertical"> 
      <TextBlock Foreground = "{StaticResource myBrush}" Text = "First Name" 
         Width = "100" Margin = "10" /> 
      <TextBlock Foreground = "{StaticResource myBrush}" Text = "Last Name" 
         Width = "100" Margin = "10"/> 
   </StackPanel> 
	
</Window>

Ecco l'implementazione in DictionaryWithBrush.xaml -

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> 
	
   <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
	
</ResourceDictionary>

Ecco l'implementazione in app.xaml -

<Application x:Class = "XAMLResources.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   StartupUri = "MainWindow.xaml"> 
	
   <Application.Resources> 
      <ResourceDictionary Source = " XAMLResources\ResourceDictionaries\DictionaryWithBrush.xaml" /> 
   </Application.Resources> 
	
</Application>

Quando il codice precedente viene compilato ed eseguito, produrrà il seguente output:

Ti consigliamo di eseguire il codice sopra e sperimentare con altre risorse come il colore di sfondo, ecc.

Un modello descrive l'aspetto generale e l'aspetto visivo di un controllo. Ad ogni controllo è associato un modello predefinito che conferisce l'aspetto a quel controllo.

In XAML puoi creare facilmente i tuoi modelli quando vuoi personalizzare il comportamento visivo e l'aspetto visivo di un controllo. La connettività tra la logica e il modello può essere ottenuta mediante l'associazione dei dati.

La principale differenza tra stili e modelli sono:

  • Gli stili possono modificare solo l'aspetto del controllo con le proprietà predefinite di quel controllo.

  • Con i modelli, puoi accedere a più parti di un controllo rispetto agli stili. È inoltre possibile specificare sia il comportamento esistente che quello nuovo di un controllo.

Esistono due tipi di modelli più comunemente utilizzati.

  • Modello di controllo
  • Modello di dati

Modello di controllo

Il modello di controllo definisce o specifica l'aspetto visivo e la struttura di un controllo. Tutti gli elementi dell'interfaccia utente hanno un aspetto e un comportamento, ad esempio Button ha un aspetto e un comportamento. L'evento di clic o gli eventi di passaggio del mouse sono i comportamenti che vengono attivati ​​in risposta a un clic e al passaggio del mouse e c'è anche un aspetto predefinito del pulsante che può essere modificato dal modello di controllo.

Diamo nuovamente un'occhiata a un semplice esempio in cui vengono creati due pulsanti con alcune proprietà. Uno è contemplate e l'altro è con il default pulsante.

<Window x:Class = "TemplateDemo.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources>
      <ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
         <Grid>
            <Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" >
               <Ellipse.Fill> 
                  <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                     <GradientStop Offset = "0" Color = "Red"/>
                     <GradientStop Offset = "1" Color = "Orange"/>
                  </LinearGradientBrush> 
               </Ellipse.Fill>
            </Ellipse>
            <ContentPresenter Content = "{TemplateBinding Content}"
               HorizontalAlignment = "Center" VerticalAlignment = "Center" />
         </Grid>
         <ControlTemplate.Triggers> 
            <Trigger Property = "IsMouseOver" Value = "True">
               <Setter TargetName = "ButtonEllipse" Property = "Fill" >
                  <Setter.Value> 
                     <LinearGradientBrush StartPoint = "0,0.2" EndPoint="0.2,1.4"> 
                        <GradientStop Offset = "0" Color = "YellowGreen"/>
                        <GradientStop Offset = "1" Color = "Gold"/>
                     </LinearGradientBrush> 
                  </Setter.Value> 
               </Setter>
            </Trigger> 
				
            <Trigger Property = "IsPressed" Value = "True"> 
               <Setter Property = "RenderTransform"> 
                  <Setter.Value> 
                     <ScaleTransform ScaleX = "0.8" ScaleY = "0.8" CenterX = "0" CenterY = "0" /> 
                  </Setter.Value> 
               </Setter> 
					
               <Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" /> 
            </Trigger>
         </ControlTemplate.Triggers>
      </ControlTemplate> 
   </Window.Resources>
	
   <StackPanel> 
      <Button Content = "Round Button!" Template = "{StaticResource ButtonTemplate}" 
         Width = "150" Margin = "50" />
      <Button Content = "Default Button!" Height = "40" Width = "150" Margin = "5" /> 
   </StackPanel> 
	
</Window>

Quando il codice precedente viene compilato ed eseguito, produrrà la seguente MainWindow:

Quando passi il mouse sul pulsante con il modello personalizzato, cambia anche il colore come mostrato di seguito -

Modello di dati

Un modello di dati definisce e specifica l'aspetto e la struttura della raccolta di dati. Offre la flessibilità di formattare e definire la presentazione dei dati su qualsiasi elemento dell'interfaccia utente. Viene utilizzato principalmente sui controlli Item relativi ai dati come ComboBox, ListBox, ecc.

Diamo un'occhiata a un semplice esempio di modello di dati. Il codice XAML seguente crea una casella combinata con modello di dati e blocchi di testo.

<Window x:Class = "XAMLDataTemplate.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid VerticalAlignment = "Top">
      <ComboBox Name = "Presidents" ItemsSource = "{Binding}" Height = "30" Width = "400"> 
         <ComboBox.ItemTemplate> 
            <DataTemplate>
               <StackPanel Orientation = "Horizontal" Margin = "2">
                  <TextBlock Text = "Name: " Width = "95" Background = "Aqua" Margin = "2" /> 
                  <TextBlock Text = "{Binding Name}" Width = "95" Background = "AliceBlue" Margin = "2" /> 
                  <TextBlock Text = "Title: " Width = "95" Background = "Aqua" Margin = "10,2,0,2" />
                  <TextBlock Text = "{Binding Title}" Width = "95" Background = "AliceBlue" Margin = "2" /> 
               </StackPanel>
            </DataTemplate>
         </ComboBox.ItemTemplate> 
      </ComboBox> 
   </Grid>
   
</Window>

Ecco l'implementazione in C # in cui l'oggetto dipendente viene assegnato a DataContext:

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLDataTemplate { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() {
         InitializeComponent(); 
         DataContext = Employee.GetEmployees(); 
      }
   }
}

Ecco l'implementazione in C # per la classe Employee:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Runtime.CompilerServices; 
using System.Text; 
using System.Threading.Tasks;

namespace XAMLDataTemplate { 
   public class Employee : INotifyPropertyChanged {
      private string name; public string Name {
         get { return name; } 
         set { name = value; RaiseProperChanged(); } 
      }
      private string title; public string Title { 
         get { return title; } 
         set { title = value; RaiseProperChanged(); } 
      }
      public static Employee GetEmployee() {
         var emp = new Employee() { 
            Name = "Waqas", Title = "Software Engineer" };
         return emp; 
      }
      public event PropertyChangedEventHandler PropertyChanged;
      private void RaiseProperChanged( [CallerMemberName] string caller = ""){
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(caller)); 
         } 
      }
      public static ObservableCollection<Employee> GetEmployees() {
         var employees = new ObservableCollection<Employee>();
         employees.Add(new Employee() { Name = "Ali", Title = "Developer" }); 
         employees.Add(new Employee() { Name = "Ahmed", Title = "Programmer" });
         employees.Add(new Employee() { Name = "Amjad", Title = "Desiner" });
         employees.Add(new Employee() { Name = "Waqas", Title = "Programmer" }); 
         employees.Add(new Employee() { Name = "Bilal", Title = "Engineer" });
         employees.Add(new Employee() { Name = "Waqar", Title = "Manager" }); 
         return employees; 
      }
   }
}

Quando il codice precedente viene compilato ed eseguito, produrrà il seguente output. Contiene una casella combinata e quando fai clic sulla casella combinata, vedi che la raccolta di dati che vengono creati nella classe Employee è elencata come elementi della casella combinata.

Ti consigliamo di eseguire il codice sopra e sperimentarlo.

Il framework XAML offre diverse strategie per personalizzare e personalizzare l'aspetto di un'applicazione. Gli stili ci danno la flessibilità di impostare alcune proprietà di un oggetto e riutilizzare queste impostazioni specifiche su più oggetti per un aspetto coerente.

  • Negli stili è possibile impostare solo le proprietà esistenti di un oggetto come Altezza, Larghezza e Dimensione carattere.

  • È possibile specificare solo il comportamento predefinito di un controllo.

  • È possibile aggiungere più proprietà in un unico stile.

Gli stili vengono utilizzati per dare un aspetto uniforme a una serie di controlli. Gli stili impliciti vengono utilizzati per applicare un aspetto a tutti i controlli di un determinato tipo e semplificare l'applicazione.

Immagina di avere tre pulsanti e tutti devono avere lo stesso aspetto: stessa larghezza e altezza, stessa dimensione del carattere e stesso colore di primo piano. Possiamo impostare tutte queste proprietà sugli stessi elementi del pulsante e questo è ancora abbastanza ok per tutti i pulsanti, come mostrato nel diagramma seguente.

Ma in un'app nella vita reale, in genere ne avrai molte di più che devono avere esattamente lo stesso aspetto. E non solo i pulsanti, ovviamente, in genere vorrai che i tuoi blocchi di testo, caselle di testo e caselle combinate, ecc., Abbiano lo stesso aspetto su tutta la tua App. Sicuramente ci deve essere un modo migliore per raggiungere questo obiettivo - è noto comestyling. Si può pensare a uno stile come a un modo conveniente per applicare un insieme di valori di proprietà a più di un elemento, come mostrato nel diagramma seguente.

Diamo un'occhiata all'esempio che contiene tre pulsanti creati in XAML con alcune proprietà.

<Window x:Class = "XAMLStyle.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:local = "clr-namespace:XAMLStyle" mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button Content = "Button1" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/>
      
      <Button Content = "Button2" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/>
      
      <Button Content = "Button3" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/> 
   </StackPanel> 
	
</Window>

Quando guardi il codice sopra, vedrai che per tutti i pulsanti, altezza, larghezza, colore di primo piano, dimensione del carattere e proprietà del margine rimangono gli stessi. Quando il codice precedente viene compilato ed eseguito, verrà visualizzato il seguente output:

Ora diamo un'occhiata allo stesso esempio, ma questa volta useremo style.

<Window x:Class = "XAMLStyle.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:local = "clr-namespace:XAMLStyle" mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Style x:Key = "myButtonStyle" TargetType = "Button">
         <Setter Property = "Height" Value = "30"/> 
         <Setter Property = "Width" Value = "80"/> 
         <Setter Property = "Foreground" Value = "Blue"/> 
         <Setter Property = "FontSize" Value = "12"/> 
         <Setter Property = "Margin" Value = "10"/> 
      </Style>
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Button1" Style = "{StaticResource myButtonStyle}"/>
      <Button Content = "Button2" Style = "{StaticResource myButtonStyle}"/>
      <Button Content = "Button3" Style = "{StaticResource myButtonStyle}"/>
   </StackPanel>
	
</Window>

Gli stili sono definiti nel dizionario delle risorse e ogni stile ha un identificatore di chiave univoco e un tipo di destinazione. All'interno di <style>, puoi vedere che più tag setter sono definiti per ogni proprietà che sarà inclusa nello stile.

Nell'esempio precedente, tutte le proprietà comuni di ogni pulsante sono ora definite nello stile e quindi lo stile viene assegnato a ciascun pulsante con una chiave univoca impostando la proprietà dello stile tramite l'estensione di markup StaticResource.

Quando il codice precedente viene compilato ed eseguito, produrrà la seguente finestra che è lo stesso output.

Il vantaggio di farlo in questo modo è immediatamente evidente. Possiamo riutilizzare quello stile ovunque nel suo ambito e, se dobbiamo cambiarlo, lo cambiamo semplicemente una volta nella definizione dello stile invece che su ogni elemento.

In quale livello viene definito uno stile limita istantaneamente la portata di quello stile. Quindi l'ambito, cioè dove puoi usare lo stile, dipende da dove lo hai definito. Lo stile può essere definito sui seguenti livelli:

Suor n Livelli e descrizione
1 Livello di controllo

La definizione di uno stile a livello di controllo può essere applicata solo a quel particolare controllo.

2 Livello layout

La definizione di uno stile a qualsiasi livello di layout può essere accessibile solo da quel layout e solo dai suoi elementi figlio.

3 Livello finestra

La definizione di uno stile a livello di finestra può essere accessibile da tutti gli elementi di quella finestra.

4 Livello di applicazione

La definizione di uno stile a livello di app lo rende accessibile nell'intera applicazione.

Fondamentalmente, un trigger consente di modificare i valori delle proprietà o intraprendere azioni in base al valore di una proprietà. Quindi, fondamentalmente ti consente di modificare dinamicamente l'aspetto e / o il comportamento del tuo controllo senza doverne creare uno nuovo.

I trigger vengono utilizzati per modificare il valore di una determinata proprietà, quando sono soddisfatte determinate condizioni. I trigger sono generalmente definiti in uno stile o nella radice di un documento che vengono applicati a quel controllo specifico. Esistono tre tipi di trigger:

  • Trigger di proprietà
  • Trigger di dati
  • Trigger di eventi

Trigger di proprietà

Nei trigger di proprietà, quando si verifica una modifica in una proprietà, verrà apportata una modifica immediata o animata in un'altra proprietà. Ad esempio, è possibile utilizzare un trigger di proprietà se si desidera modificare l'aspetto del pulsante quando il mouse si trova sopra il pulsante.

Esempio

L'esempio seguente mostra come modificare il colore di primo piano di un pulsante quando il mouse entra nella sua regione.

<Window x:Class = "XAMLPropertyTriggers.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources>
      <Style x:Key = "TriggerStyle" TargetType = "Button">
         <Setter Property = "Foreground" Value = "Blue" />
         <Style.Triggers>
            <Trigger Property = "IsMouseOver" Value = "True">
               <Setter Property = "Foreground" Value = "Green" />
            </Trigger> 
         </Style.Triggers>
      </Style>
   </Window.Resources>
	
   <Grid>
      <Button Width = "100" Height = "70" Style = "{StaticResource TriggerStyle}" 
         Content = "Trigger"/>
   </Grid>
	
</Window>

Quando compili ed esegui il codice sopra, produrrà il seguente output:

Quando il mouse entra nella regione del pulsante, il colore di primo piano diventerà verde.

Trigger di dati

Un trigger di dati esegue un'azione quando i dati associati soddisfano una determinata condizione. Diamo un'occhiata al seguente codice XAML in cui vengono creati una casella di controllo e un blocco di testo con alcune proprietà. Quando la casella di controllo è selezionata, cambierà il colore di primo piano in rosso.

<Window x:Class = "XAMLDataTrigger.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Data Trigger" Height = "350" Width = "604">
	
   <StackPanel HorizontalAlignment = "Center">
      <CheckBox x:Name = "redColorCheckBox" Content = "Set red as foreground color" Margin = "20"/>
		
      <TextBlock Name = "txtblock" VerticalAlignment = "Center" 
         Text = "Event Trigger" FontSize = "24" Margin = "20">
         <TextBlock.Style>
            <Style>
               <Style.Triggers>
                  <DataTrigger Binding = "{Binding ElementName = redColorCheckBox, Path = IsChecked}" 
                     Value = "true">
                     <Setter Property = "TextBlock.Foreground" Value = "Red"/>
                     <Setter Property = "TextBlock.Cursor" Value = "Hand" />
                  </DataTrigger>
               </Style.Triggers>
            </Style>
         </TextBlock.Style>
      </TextBlock>
   </StackPanel>
	
</Window>

Quando compili ed esegui il codice sopra, produrrà il seguente output:

Quando la casella di controllo è selezionata, il colore di primo piano del blocco di testo diventerà rosso.

Trigger di eventi

Un trigger di evento esegue un'azione quando viene generato un evento specifico. Di solito viene utilizzato per realizzare alcune animazioni come DoubleAnimation, ColorAnimation, ecc. Il seguente blocco di codice crea un semplice pulsante. Quando viene generato l'evento clic, espanderà la larghezza e l'altezza del pulsante.

<Window x:Class = "XAMLEventTrigger.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <Button Content = "Click Me" Width = "60" Height = "30">
         <Button.Triggers>
            <EventTrigger RoutedEvent = "Button.Click">
               <EventTrigger.Actions>
                  <BeginStoryboard>
                     <Storyboard>
                     
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Width" Duration = "0:0:4">
                           <LinearDoubleKeyFrame Value = "60" KeyTime = "0:0:0"/>
                           <LinearDoubleKeyFrame Value = "120" KeyTime = "0:0:1"/>
                           <LinearDoubleKeyFrame Value = "200" KeyTime = "0:0:2"/>
                           <LinearDoubleKeyFrame Value = "300" KeyTime = "0:0:3"/>
                        </DoubleAnimationUsingKeyFrames>
							
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Height" Duration = "0:0:4">
                           <LinearDoubleKeyFrame Value = "30" KeyTime = "0:0:0"/>
                           <LinearDoubleKeyFrame Value = "40" KeyTime = "0:0:1"/>
                           <LinearDoubleKeyFrame Value = "80" KeyTime = "0:0:2"/>
                           <LinearDoubleKeyFrame Value = "150" KeyTime = "0:0:3"/>
                        </DoubleAnimationUsingKeyFrames>
							
                     </Storyboard>
                  </BeginStoryboard>
               </EventTrigger.Actions>
            </EventTrigger>
         </Button.Triggers>
      </Button>
   </Grid>
</Window>

Quando compili ed esegui il codice sopra, produrrà il seguente output:

Ora, fai clic sul pulsante e noterai che inizierà ad espandersi in entrambe le dimensioni.

Se hai familiarità con il debug in qualsiasi linguaggio procedurale (come C #, C / C ++ ecc.) E conosci l'uso di breake ti aspettano lo stesso tipo di debug in XAML, quindi sarai sorpreso di sapere che non è ancora possibile eseguire il debug di un codice XAML come il modo in cui eseguivi il debug di qualsiasi altro codice di linguaggio procedurale. Eseguire il debug di un'app XAML significa cercare di trovare un errore;

  • Nel data binding, i tuoi dati non vengono visualizzati sullo schermo e non sai perché

  • Oppure un problema è correlato a layout complessi.

  • O un problema di allineamento o problemi nel colore dei margini, sovrapposizioni, ecc. Con alcuni modelli estesi come ListBox e casella combinata.

Il debug in XAML è qualcosa che in genere fai per verificare se le tue associazioni funzionano e, se non funziona, per verificare cosa non va. Sfortunatamente, l'impostazione dei punti di interruzione nelle associazioni XAML non è possibile tranne che in Silverlight, ma possiamo usare la finestra di output per verificare la presenza di errori di associazione dei dati. Diamo un'occhiata al seguente codice XAML per trovare l'errore nel data binding.

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0">
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/>
         </StackPanel>
			
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0">
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width="100" Text = "{Binding Title}" />
         </StackPanel>
      </StackPanel>
   </Grid>
	
</Window>

Le proprietà di testo dei due blocchi di testo sono impostate su "Nome" e "Titolo" staticamente, mentre le proprietà di testo degli altri due blocchi di testo sono vincolate a "Nome" e "Titolo". Ma le variabili di classe sono intenzionalmente prese come nome e titolo nella classe Employee che sono nomi di variabili errati. Cerchiamo ora di capire dove possiamo trovare questo tipo di errore quando l'output desiderato non viene mostrato.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace DataBindingOneWay {
   public class Employee {
      public string Name { get; set; } 
      public string Title { get; set; }
		
      public static Employee GetEmployee() {
         var emp = new Employee() {
            Name = "Ali Ahmed", 
            Title = "Developer"
         };
         return emp; 
      }
   }
}

Ecco l'implementazione della classe MainWindow nel codice C # -

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace DataBindingOneWay {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() {
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      }
   }
}

Eseguiamo questa applicazione e puoi vedere immediatamente nella nostra MainWindow che siamo stati associati con successo al titolo di quell'oggetto Employee ma il nome non è associato.

Per verificare cosa è successo con il nome, diamo un'occhiata alla finestra di output in cui viene generato un sacco di log.

Il modo più semplice per trovare un errore è cercare semplicemente l'errore e troverai l'errore indicato di seguito che dice "Errore di percorso BindingExpression: proprietà 'FirstName' non trovata su 'object' '' Employe"

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode = 11611730)'.
BindingExpression:Path = FirstName; 
DataItem = 'Employee' (HashCode = 11611730); target element is 'TextBlock' (Name = ''); 
target property is 'Text' (type 'String')

Che indica chiaramente che FirstName non è un membro della classe Employee, quindi aiuta a risolvere questo tipo di problemi nella tua applicazione.

Quando cambi il file FirstName per Name di nuovo, vedrai l'output desiderato.

Strumenti di debug dell'interfaccia utente per XAML

Gli strumenti di debug dell'interfaccia utente per XAML vengono introdotti con Visual Studio 2015 per ispezionare il codice XAML in fase di esecuzione. Con l'aiuto di questi strumenti, il codice XAML viene presentato sotto forma di albero visuale dell'applicazione WPF in esecuzione e anche le diverse proprietà dell'elemento dell'interfaccia utente nell'albero. Per abilitare questo strumento, seguire i passaggi indicati di seguito.

  • Step 1 - Vai al menu Strumenti e seleziona Opzioni dal menu Strumenti.

  • Step 2 - Vedrai la seguente finestra di dialogo.

  • Step 3 - Vai alle Opzioni generali sotto la voce Debug sul lato sinistro.

  • Step 4 - Seleziona l'opzione evidenziata, ad esempio "Abilita strumenti di debug dell'interfaccia utente per XAML"

  • Step 5 - Premere il pulsante OK.

Ora esegui qualsiasi applicazione XAML o usa il codice XAML seguente:

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <StackPanel>
      <ComboBox Name = "comboBox" Margin = "50" Width = "100">
         <ComboBoxItem Content = "Green"/>
         <ComboBoxItem Content = "Yellow" IsSelected = "True"/>
         <ComboBoxItem Content = "Orange" />
      </ComboBox>
		
      <TextBox Name = "textBox" Margin = "50" Width = "100" 
         Height = "23" VerticalAlignment = "Top" Text = "{
         Binding ElementName = comboBox, Path = SelectedItem.Content, 
         Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox>
   </StackPanel>
	
</Window>

Quando l'applicazione viene eseguita, mostrerà l'albero visivo live in cui tutti gli elementi sono mostrati in un albero.

Questo albero visivo live mostra la struttura completa del layout per capire dove sono posizionati gli elementi dell'interfaccia utente. Ma questa opzione è disponibile solo in Visual Studio 2015. Se stai utilizzando una versione precedente di Visual Studio, non puoi utilizzare questo strumento; tuttavia esiste un altro strumento che può essere integrato con Visual Studio come XAML Spy per Visual Studio. Puoi scaricarlo dahttp://xamlspy.com/download. Ti consigliamo di scaricare questo strumento se stai usando una versione precedente di Visual Studio.

XAML ha una delle funzionalità più potenti fornite per creare controlli personalizzati che rendono molto facile creare controlli ricchi di funzionalità e personalizzabili. I controlli personalizzati vengono utilizzati quando tutto il built-in controlli forniti da Microsoft non stanno adempiendo ai suoi criteri o non si vogliono pagare per 3 rd controlli di partito.

In questo capitolo imparerai come creare controlli personalizzati. Prima di iniziare a dare un'occhiata ai controlli personalizzati, diamo prima una rapida occhiata a un controllo utente.

Controllo utente

I controlli utente forniscono una tecnica per raccogliere e combinare diversi controlli incorporati insieme e impacchettarli in XAML riutilizzabile. I controlli utente vengono utilizzati nei seguenti scenari:

  • Se il controllo è costituito da controlli esistenti, ovvero è possibile creare un singolo controllo di più controlli già esistenti.

  • Se il controllo non necessita di supporto per la creazione dei temi. I controlli utente non supportano personalizzazioni complesse, modelli di controllo e anche stili difficili.

  • Se uno sviluppatore preferisce scrivere i controlli utilizzando il modello code-behind in cui viene scritta una vista e quindi un codice diretto per i gestori di eventi.

  • Non condividerai il tuo controllo tra le applicazioni.

Facciamo un esempio di controllo utente e seguiamo i passaggi indicati di seguito:

  • Step 1 - Crea un nuovo progetto WPF, quindi fai clic con il pulsante destro del mouse sulla soluzione e seleziona Aggiungi> Nuovo elemento ...

  • Step 2 - Si aprirà la seguente finestra di dialogo, ora seleziona User Control (WPF) e nominalo MyUserControl.

  • Step 3 - Fai clic sul pulsante Aggiungi e vedrai che due nuovi file (MyUserControl.xaml e MyUserControl.cs) verranno aggiunti alla tua soluzione.

Di seguito è riportato il codice XAML in cui vengono creati un pulsante e una casella di testo con alcune proprietà nel file MyUserControl.xaml.

<UserControl x:Class = "XAMLUserControl.MyUserControl" 
   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"
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">
	
   <Grid>
      <TextBox Height = "23" HorizontalAlignment = "Left" 
         Margin = "80,49,0,0" Name = "txtBox" VerticalAlignment = "Top" Width = "200" />
      <Button Content = "Click Me" Height = "23" 
         HorizontalAlignment = "Left" Margin = "96,88,0,0" Name = "button" 
         VerticalAlignment = "Top" Width = "75" Click = "button_Click" />
   </Grid>
	
</UserControl>

Di seguito è riportato il codice C # per l'evento clic sul pulsante nel file MyUserControl.cs che aggiorna la casella di testo.

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLUserControl {
   /// <summary> 
      /// Interaction logic for MyUserControl.xaml
   /// </summary> 
	
   public partial class MyUserControl : UserControl {
      public MyUserControl() {
         InitializeComponent(); 
      }
      private void button_Click(object sender, RoutedEventArgs e) { 
         txtBox.Text = "You have just clicked the button"; 
      } 
   }
}

Ecco l'implementazione in MainWindow.xaml per aggiungere il controllo utente.

<Window x:Class = "XAMLUserControl.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:control = "clr-namespace:XAMLUserControl" 
   Title = "MainWindow" Height = "350" Width = "525">
	
   <Grid>
      <control:MyUserControl/>
   </Grid>
	
</Window>

Quando compili ed esegui il codice sopra, produrrà il seguente output:

Ora fai clic sul pulsante "Cliccami" e vedrai che il testo della casella di testo è aggiornato.

Controlli personalizzati

Un controllo personalizzato è una classe che offre il proprio stile e modello normalmente definiti in generic.xaml. I controlli personalizzati vengono utilizzati nei seguenti scenari,

  • Se il controllo non esiste e devi crearlo da zero.

  • Se desideri estendere o aggiungere funzionalità a un controllo preesistente aggiungendo una proprietà extra o una funzionalità extra per adattarsi al tuo scenario specifico.

  • Se i controlli devono supportare la creazione di temi e lo stile.

  • Se vuoi condividere il tuo controllo tra le applicazioni.

Facciamo un esempio di controllo personalizzato e seguiamo i passaggi indicati di seguito.

  • Step 1 - Crea un nuovo progetto WPF, quindi fai clic con il pulsante destro del mouse sulla soluzione e seleziona Aggiungi> Nuovo elemento ...

  • Step 2- Si aprirà la seguente finestra di dialogo. Ora selezionaCustom Control (WPF) e nominalo MyCustomControl.

  • Step 3 - Fai clic sul pulsante Aggiungi e vedrai che due nuovi file (Themes / Generic.xaml e MyCustomControl.cs) verranno aggiunti alla tua soluzione.

Di seguito è riportato il codice XAML in cui è impostato lo stile per il controllo personalizzato nel file Generic.xaml.

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLCustomControls">
	
   <Style TargetType = "{x:Type local:MyCustomControl}"
      BasedOn = "{StaticResource {x:Type Button}}"> 
      <Setter Property = "Background" Value = "LightSalmon"/>
      <Setter Property = "Foreground" Value = "Blue"/>
   </Style>
	
</ResourceDictionary>

Di seguito è riportato il codice C # per la classe MyCustomControl che viene ereditato dalla classe button e nel costruttore sostituisce i metadati.

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLCustomControls {
   public class MyCustomControl : Button {
      static MyCustomControl() {
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl)));
      }
   }
}

Di seguito è riportata l'implementazione dell'evento clic del controllo personalizzato in C # che aggiorna il testo del blocco di testo.

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLCustomControls {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void customControl_Click(object sender, RoutedEventArgs e) {
         txtBlock.Text = "You have just click your custom control"; 
      } 
   }
}

Ecco l'implementazione in MainWindow.xaml per aggiungere il controllo personalizzato e un TextBlock.

<Window x:Class = "XAMLCustomControls.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:control = "clr-namespace:XAMLCustomControls" Title = "MainWindow"
   Height = "350" Width = "604">
	
   <StackPanel>
      <control:MyCustomControl x:Name = "customControl" 
         Content = "Click Me" Width = "70" Margin = "10" Click = "customControl_Click"/>
      <TextBlock Name = "txtBlock" Width = "250" Height = "30"/>
   </StackPanel>
	
</Window>

Quando compili ed esegui il codice precedente, produrrà il seguente output. Osserva che l'output contiene un controllo personalizzato che è un pulsante personalizzato.

Ora fai clic sul pulsante personalizzato. Vedrai che il testo del blocco di testo viene aggiornato.