Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - [Vb.net Wpf] Auito personalizzazione template Window
Forum - C# / VB.NET - [Vb.net Wpf] Auito personalizzazione template Window

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Sevenjeak (Normal User)
Pro


Messaggi: 91
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 10:55
Martedì, 18/09/2012
Ultimamente sto passando alla realizzazione di piccole applicazione wpf, utilizzando il linguaggio vb, sto iniziando a personalizzare il template, la parte grafica, degli elementi presenti nella finestra, tra qui la finestra stessa, per fare questo ho semplicemente fatto uno stile che leva il bordo alla finestra e la rende trasparente, per poi disegnarsi sopra, con forme, bordi e altro.., tutto questo modificando il codice all'interno del file Application.xaml in questo modo:

Codice sorgente - presumibilmente Plain Text

  1. <Application x:Class="Application"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.     StartupUri="MainWindow.xaml">
  4.     <Application.Resources>
  5.         <Style x:Key="WinStyle" TargetType="{x:Type Window}">
  6.             <Setter Property="WindowStyle" Value="None" />
  7.             <Setter Property="AllowsTransparency" Value="True" />
  8.             <Setter Property="Template">
  9.                 <Setter.Value>
  10.                     <ControlTemplate TargetType="{x:Type Window}">
  11.                         <Border Background="LightGray" BorderBrush="Gray" BorderThickness="1" CornerRadius="7">
  12.                             <Grid Margin="5">
  13.                                 <Grid.RowDefinitions>
  14.                                     <RowDefinition Height="auto"></RowDefinition>
  15.                                     <RowDefinition></RowDefinition>
  16.                                     <RowDefinition Height="auto"></RowDefinition>
  17.                                 </Grid.RowDefinitions>
  18.                                 <Grid.ColumnDefinitions>
  19.                                     <ColumnDefinition Width="auto"></ColumnDefinition>
  20.                                     <ColumnDefinition></ColumnDefinition>
  21.                                     <ColumnDefinition Width="auto"></ColumnDefinition>
  22.                                 </Grid.ColumnDefinitions>
  23.                                 <TextBlock Grid.Row="0" Grid.Column="1" Text="Titolo" />
  24.                                 <Image Grid.Row="0" Grid.Column="2" Source="module-close.png" MouseDown="Close_click"/>
  25.                             </Grid>
  26.                         </Border>
  27.                     </ControlTemplate>
  28.                 </Setter.Value>
  29.             </Setter>
  30.         </Style>
  31.     </Application.Resources>
  32. </Application>



A questo punto mi basterebbe richiamare lo stile appena realizzato e tutto funziona, avrei solamente delle piccole domande:

Nel mio template ho messo un textblock che dovrebbe contenere il titolo dell'applicazione, come posso far si che il testo di questa textblock sia identico al valore della proprietà title di Window ( la finestra dell'applicazione )?

Dopo aver fatto queste modifiche nell'xaml principale ( quella dell'applicazione ) non mi visualizza più, all'interno del tag <Window> il tag <grid>, almeno che non lo inserisco io manualmente, come mai questo?

E' possibile fare in modo che, la finestra mi abbia di default questo template, senza che lo richiamo tramite l'attributo style?

Non so se sono stato abbastanza chiaro con le mie domande, ma e da parecchi giorni che cerco delle risposte su internet senza nessun risultato.

PM Quote
Avatar
tasx (Dev Team)
Expert


Messaggi: 439
Iscritto: 15/12/2008

Segnala al moderatore
Postato alle 14:54
Martedì, 18/09/2012
Ciao per la prima domanda hai due soluzioni:
1) usare il pattern MVVM quindi creare un viewmodel e bindare la proprietà Text del textblock ad una proprietà del viewmodel e poi il titolo della finestra alla proprietà di prima;
2) penso che tu protesti farlo anche via codice, anche se te lo sconsiglio...

Codice sorgente - presumibilmente Plain Text

  1. <Window x:Class="WpfApplication3.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         Height="350" Width="525"
  5.         WindowStyle="None" AllowsTransparency="True" Title="{Binding Titolo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
  6.     <Grid>
  7.         <Border Background="LightGray" BorderBrush="Gray" BorderThickness="1" CornerRadius="7">
  8.             <Grid Margin="5">
  9.                 <Grid.RowDefinitions>
  10.                     <RowDefinition Height="auto"></RowDefinition>
  11.                     <RowDefinition></RowDefinition>
  12.                     <RowDefinition Height="auto"></RowDefinition>
  13.                 </Grid.RowDefinitions>
  14.                 <Grid.ColumnDefinitions>
  15.                     <ColumnDefinition Width="auto"></ColumnDefinition>
  16.                     <ColumnDefinition></ColumnDefinition>
  17.                     <ColumnDefinition Width="auto"></ColumnDefinition>
  18.                 </Grid.ColumnDefinitions>
  19.                 <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Titolo}" />
  20.                 <Image Grid.Row="0" Grid.Column="2"/>
  21.             </Grid>
  22.         </Border>
  23.     </Grid>
  24. </Window>



ecco la riusposta alla tua seconda domanda, facendo così la finestra sarà sempre come chiedi senza applicare nessun stile. Poi vedi che le proprietà Text del TextBloc è bindata ad un'altra proprietà definita nel viewmodel e come vedi anche la proprietà title è bindata alla stessa proprietà Titolo del viewmodel...

questo è il viewmodel:
Codice sorgente - presumibilmente Delphi

  1. using GalaSoft.MvvmLight;
  2.  
  3. namespace WpfApplication3.ViewModel
  4. {
  5.     /// <summary>
  6.     /// This class contains properties that the main View can data bind to.
  7.     /// <para>
  8.     /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
  9.     /// </para>
  10.     /// <para>
  11.     /// You can also use Blend to data bind with the tool's support.
  12.     /// </para>
  13.     /// <para>
  14.     /// See http://www.galasoft.ch/mvvm
  15.     /// </para>
  16.     /// </summary>
  17.     public class MainViewModel : ViewModelBase
  18.     {
  19.         /// <summary>
  20.         /// Initializes a new instance of the MainViewModel class.
  21.         /// </summary>
  22.         public MainViewModel()
  23.         {
  24.             Titolo = "Ciao mondo";
  25.         }
  26.  
  27.         private string _titolo { get; set; }
  28.         public string Titolo
  29.         {
  30.             get { return _titolo; }
  31.             set
  32.             {
  33.                 _titolo = value;
  34.                 RaisePropertyChanged("Titolo");
  35.             }
  36.         }
  37.     }
  38. }



una volta che la proprietà Titolo viene cambiata anche le varie proprità bindate ad esse vengono cambiate.

L'altra soluzione era quella di dichiarare il Textblock nel seguente modo:

Codice sorgente - presumibilmente Plain Text

  1. <TextBloc x:Name="textblock" Grid.Row="0" Grid.Column="1" Text="Titolo" />



e poi nel codice dietro allo xaml
Codice sorgente - presumibilmente Plain Text

  1. textblock.Text = "il mio titolo";


che poi forse è la soluzione più semplice e veloce se non vuoi fare cose complicate... :heehee::heehee::heehee:

se ha i domande o mi sono spiegato male chiedi pure!!

Ciaociao!!

PM Quote
Avatar
Sevenjeak (Normal User)
Pro


Messaggi: 91
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 15:47
Martedì, 18/09/2012
Scusa se sbaglio, ma il primo codice da te postato non è codice C#, cmq ho provato entrambi le soluzione ma non so, forse sbaglio io, ma non riesco.

PM Quote
Avatar
tasx (Dev Team)
Expert


Messaggi: 439
Iscritto: 15/12/2008

Segnala al moderatore
Postato alle 15:50
Martedì, 18/09/2012
Il primo blocco di codice è lo XAML della finestra principale, è meglio se usi la seconda soluzione, è sufficiente dare un nome al TextBlock è poi usarlo nel c# come se lo avessi già dichiarato...

PM Quote
Avatar
Sevenjeak (Normal User)
Pro


Messaggi: 91
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 16:05
Martedì, 18/09/2012
Ma io non sto facendo l'applicazione wpf in C#, ma in VB, lo scritto anche nel titolo, cmq non mi funziona neanche il secondo metodo, nel codice non mi riconosce il nome della textblock, ora cmq sto riprovando

PM Quote
Avatar
tasx (Dev Team)
Expert


Messaggi: 439
Iscritto: 15/12/2008

Segnala al moderatore
Postato alle 16:17
Martedì, 18/09/2012
Ciao, c# o vb non cambia, il problemi sono:
1) hai modificato lo XAML? Hai dichiarato le proprietà della finestra dentro il tag Window?
2) dove vai a modificare la proprietà Text del textBlock, devi farlo nella file *.cs associato allo XAML della finestra, praticamente nella classe parziale della tua window.

PM Quote
Avatar
Sevenjeak (Normal User)
Pro


Messaggi: 91
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 19:32
Martedì, 18/09/2012
Per il linguaggio mi riferivo al codice che mi hai postato te, non sapevo come riscriverlo in vb, cmq non fa niente, opto per il secondo metodo da te postato.

Come scritto da te, la textblock, lo dichiarata nel file Application.xaml, dove si trova lo stile del template, lo dichiarata in questo modo:

Codice sorgente - presumibilmente Plain Text

  1. <TextBlock x:Name="winTitle" Padding="7"  Grid.Row="0" Grid.Column="1" Text="{Binding winTitle}" />



Nel codice, precisamente nella runtime Window_Loaded, inserisco questo codice:

Codice sorgente - presumibilmente Plain Text

  1. winTitle.Text = Me.Title



Ma mi dice che winTitle non è dichiarata, dovrei far in modo che me la riconosca o dovrei inserire il codice da qualche altra parte?

Ultima modifica effettuata da Sevenjeak il 18/09/2012 alle 19:33
PM Quote
Avatar
Dedalux (Member)
Pro


Messaggi: 103
Iscritto: 15/12/2010

Segnala al moderatore
Postato alle 21:04
Martedì, 18/09/2012
In genere quando si vuole applicare uno stile a tutti i controlli di un tipo, si definisce lo style senza x:key, fornendo solamente il parametro TargetType

Nel caso della window però abbiamo una classe, es. MainWindow, che eredita da window. Gli styles vengono applicati solamente alle classi per cui sono stati creati, senza estensione alle classi derivate.
Per questo andrebbe definito uno stile per ogni classe che eredita da window. Nel caso di MainWindow:

importi nello xaml di application il namespace che contiene la classe che eredita da window (io l'ho chiamato local) e definisci uno stile tipo questo:

Codice sorgente - presumibilmente Plain Text

  1. <Style TargetType="{x:Type local:MainWindow}">
  2.             <Setter Property="WindowStyle"
  3.                     Value="None" />
  4.             <Setter Property="AllowsTransparency"
  5.                     Value="True" />
  6.             <Setter Property="Background"
  7.                     Value="White" />
  8.             <Setter Property="BorderThickness"
  9.                     Value="4" />
  10.  
  11.             <Setter Property="Template">
  12.                 <Setter.Value>
  13.                     <ControlTemplate TargetType="{x:Type local:MainWindow}">
  14.                         <Border BorderBrush="Black"
  15.                                 BorderThickness="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:MainWindow, AncestorLevel=1},
  16.                                                           Path=BorderThickness}"
  17.                                 CornerRadius="6">
  18.                             <Grid Background="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType=local:MainWindow, AncestorLevel=1}}" >
  19.                                 <Grid.RowDefinitions>
  20.                                     <RowDefinition Height="Auto" />
  21.                                     <RowDefinition Height="6" />
  22.                                     <RowDefinition />
  23.                                 </Grid.RowDefinitions>
  24.  
  25.                                 <TextBlock HorizontalAlignment="Left" Margin="2"
  26.                                            Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:MainWindow, AncestorLevel=1}, Path=Title}" />
  27.                                 <ContentPresenter Grid.Row="2"
  28.                                                   Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType=local:MainWindow, AncestorLevel=1}}" />
  29.  
  30.                             </Grid>
  31.                         </Border>
  32.                     </ControlTemplate>
  33.                 </Setter.Value>
  34.             </Setter>
  35.  
  36.         </Style>



altrimenti devi assegnare una key allo stile, e far si che ogni tua finestra abbia un metodo per pescare lo stile dalle risorse e impostarlo tramite code behind come ti ha consigliato qualcuno prima di me (però appunto non sarà visibile dal designer)

se hai dubbi chiedi

Ultima modifica effettuata da Dedalux il 18/09/2012 alle 21:22
PM Quote
Avatar
tasx (Dev Team)
Expert


Messaggi: 439
Iscritto: 15/12/2008

Segnala al moderatore
Postato alle 21:19
Martedì, 18/09/2012
Testo quotato

Postato originariamente da Sevenjeak:

Per il linguaggio mi riferivo al codice che mi hai postato te, non sapevo come riscriverlo in vb, cmq non fa niente, opto per il secondo metodo da te postato.

Come scritto da te, la textblock, lo dichiarata nel file Application.xaml, dove si trova lo stile del template, lo dichiarata in questo modo:

Codice sorgente - presumibilmente Plain Text

  1. <TextBlock x:Name="winTitle" Padding="7"  Grid.Row="0" Grid.Column="1" Text="{Binding winTitle}" />



Nel codice, precisamente nella runtime Window_Loaded, inserisco questo codice:

Codice sorgente - presumibilmente Plain Text

  1. winTitle.Text = Me.Title



Ma mi dice che winTitle non è dichiarata, dovrei far in modo che me la riconosca o dovrei inserire il codice da qualche altra parte?



Ciao, guarda che il textblock nell'esempio che ti ho riportato lo dichiaro all'interno della Window, altrimenti non lo trova, poi se non usi la seconda soluzione non serve che nella definizione del TexBlock scrivi
Codice sorgente - presumibilmente Plain Text

  1. <TextBlock x:Name="winTitle" Padding="7"  Grid.Row="0" Grid.Column="1" Text="{Binding winTitle}" />


, puoi pure eliminare la proprietà Text tanto se non gli passi un Datacontext non trova il binding, quindi diventa:
Codice sorgente - presumibilmente Plain Text

  1. <TextBlock x:Name="winTitle" Padding="7"  Grid.Row="0" Grid.Column="1"/>



ora non ne sono sicuro ma se dichiari il textblock all'interno di un template non penso tu possa usarlo da codice(più ci penso e più ne sono sicuro ;);) ), guarda bene il mio primo codice(che ti ripropongo):
Codice sorgente - presumibilmente Plain Text

  1. <Window x:Class="WpfApplication3.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         Height="350" Width="525"
  5.         WindowStyle="None" AllowsTransparency="True" Title="MainWindow">
  6.     <Grid>
  7.         <Border Background="LightGray" BorderBrush="Gray" BorderThickness="1" CornerRadius="7">
  8.             <Grid Margin="5">
  9.                 <Grid.RowDefinitions>
  10.                     <RowDefinition Height="auto"></RowDefinition>
  11.                     <RowDefinition></RowDefinition>
  12.                     <RowDefinition Height="auto"></RowDefinition>
  13.                 </Grid.RowDefinitions>
  14.                 <Grid.ColumnDefinitions>
  15.                     <ColumnDefinition Width="auto"></ColumnDefinition>
  16.                     <ColumnDefinition></ColumnDefinition>
  17.                     <ColumnDefinition Width="auto"></ColumnDefinition>
  18.                 </Grid.ColumnDefinitions>
  19.                 <TextBlock x:Name="winTitle" Grid.Row="0" Grid.Column="1" />
  20.                 <Image Grid.Row="0" Grid.Column="2"/>
  21.             </Grid>
  22.         </Border>
  23.     </Grid>
  24. </Window>



se noti il contenuto della Window viene inserito direttamente senza applicargli nessun stile...

Dunque nel costruttore(o in qualsiasi altro metodo) del file MainWindow.xaml.cs(o come si chiama ;) ) usi questo:
Codice sorgente - presumibilmente Plain Text

  1. winTitle.Text = Me.Title



ciaociao :k::k:

Ultima modifica effettuata da tasx il 18/09/2012 alle 21:20
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo