2009-05-05 11 views
8

Per quelli di voi utilizzando Expression Blend così come Visual Studio nei vostri progetti reali, ti prego, aiutami a capire come si utilizza miscela e Visual Studio nella vostra attività di sviluppo/progettazione di tutti i giorni, ecco un vero e proprio scenario:Come posso utilizzare Expression Blend per modificare un DataTemplate creato in Visual Studio?

Ho creato la seguente semplice applicazione WPF in Visual Studio. Lo mostra un elenco di oggetti cliente con un DataTemplate che mostra i clienti in semplici scatole arancioni.

Io ora voglio mettere un po 'di pizazz in questo DataTemplate usando Expression Blend.

ho aprire il progetto in Expression Blend pensando che sto andando a vedere le caselle di colore arancione che io posso cambiare il colore di, creare un'animazione come io mouse su di loro, ridimensionarla, ecc, tuttavia, tutto Vedo in Expression Blend una casella completamente vuota.

così ho capito:

  • Expression Blend non riesco a capire che i miei dati viene dal ViewModel e quindi non visualizzarlo. È una limitazione di Blend o devo modificare il mio codice in qualche modo in modo che Blend possa interpretare quali dati verranno visualizzati in fase di esecuzione?
  • Utilizzo Expression Blend 3 con funzionalità di "dati di esempio". Qual è il modo migliore per utilizzare questa funzione di dati di esempio in modo che anche se non può interpretare il C# e capire quali dati usciranno dalla proprietà ViewModel per riempire la casella di riepilogo, come posso ottenerlo almeno a produrre alcuni dati fittizi in modo da poter manipolare il DataTemplate?

XAML:

<Window x:Class="TestStringFormat234.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <DataTemplate x:Key="DataTemplateCustomers"> 
      <Border CornerRadius="5" Background="Orange" Padding="5" Margin="3"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock> 
        <TextBlock.Text> 
         <MultiBinding StringFormat="{}{0} {1} (hired on {2:MMM dd, yyyy})"> 
          <Binding Path="FirstName"/> 
          <Binding Path="LastName"/> 
          <Binding Path="HireDate"/> 
         </MultiBinding> 
        </TextBlock.Text> 
        </TextBlock> 
       </StackPanel> 
      </Border> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <ListBox ItemsSource="{Binding GetAllCustomers}" 
       ItemTemplate="{StaticResource DataTemplateCustomers}"> 
     </ListBox> 
    </Grid> 
</Window> 

Codice Dietro:

using System.Windows; 
using System.Collections.ObjectModel; 
using System; 

namespace TestStringFormat234 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = new CustomerViewModel(); 
     } 
    } 

    //view model 
    public class CustomerViewModel 
    { 
     public ObservableCollection<Customer> GetAllCustomers { 
      get { 
       ObservableCollection<Customer> customers = new ObservableCollection<Customer>(); 
       customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", HireDate = DateTime.Parse("2007-12-31") }); 
       customers.Add(new Customer { FirstName = "Jack", LastName = "Jones", HireDate = DateTime.Parse("2005-12-31") }); 
       return customers; 
      } 
     } 
    } 

    //model 
    public class Customer 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public DateTime HireDate { get; set; } 
    } 
} 
+2

Perché non mettete la vostra risposta come una risposta e allora accettalo. Sarà più facile per gli altri vedere allora –

+0

Lo faccio se ricordo, ma ci sono ostacoli temporali che lo rendono difficile: devi aspettare 48 risposte prima di rispondere alla tua stessa domanda e poi altre 48 ore prima di accettarlo. –

+0

Beh, è ​​almeno nelle risposte. –

risposta

7

Ho appena capito questo modo mi permetta di rispondere alla mia domanda.

Ho letto Laurent's Bugnion enlighting article on this e ho scoperto che dovevo solo modificare il codice precedente in modo che potessi vedere i dati del mio ViewModel visualizzati nella GUI di Expression Blend ed essere stato in grado di modificare DataTemplate in Blend, salvarlo e quindi modifica continua in Visual Studio.

In pratica le modifiche sono: (1) estrarre l'istruzione DataContext dal codice sottostante, (2) aggiungere lo spazio dei nomi "locale" in XAML, (3) definire un fornitore di dati locale in XAML ("TheDataProvider"), (4) collegarlo direttamente dal ListBox.

Ecco il codice che funziona in Expression Blend e Visual Studio per intero:

XAML:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestStringFormat234" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="window" x:Class="TestStringFormat234.Window1" 
    Title="Window1" Height="300" Width="300" mc:Ignorable="d"> 
    <Window.Resources> 
     <local:CustomerViewModel x:Key="TheDataProvider"/> 

     <DataTemplate x:Key="DataTemplateCustomers"> 
      <Border CornerRadius="5" Padding="5" Margin="3"> 
       <Border.Background> 
        <LinearGradientBrush EndPoint="1.007,0.463" StartPoint="-0.011,0.519"> 
         <GradientStop Color="#FFF4EEEE" Offset="0"/> 
         <GradientStop Color="#FFA1B0E2" Offset="1"/> 
        </LinearGradientBrush> 
       </Border.Background> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock> 
        <TextBlock.Text> 
         <MultiBinding StringFormat="{}{0} {1} (hired on {2:MMM dd, yyyy})"> 
          <Binding Path="FirstName"/> 
          <Binding Path="LastName"/> 
          <Binding Path="HireDate"/> 
         </MultiBinding> 
        </TextBlock.Text> 
        </TextBlock> 
       </StackPanel> 
      </Border> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid > 
     <ListBox 
      ItemsSource="{Binding Path=GetAllCustomers, Source={StaticResource TheDataProvider}}" 
      ItemTemplate="{StaticResource DataTemplateCustomers}" /> 
    </Grid> 
</Window> 

Codice Dietro:

using System.Windows; 
using System.Collections.ObjectModel; 
using System; 

namespace TestStringFormat234 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 
    } 

    //view model 
    public class CustomerViewModel 
    { 
     public ObservableCollection<Customer> GetAllCustomers { 
      get { 
       ObservableCollection<Customer> customers = new ObservableCollection<Customer>(); 
       customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", HireDate = DateTime.Parse("2007-12-31") }); 
       customers.Add(new Customer { FirstName = "Jack", LastName = "Jones", HireDate = DateTime.Parse("2005-12-31") }); 
       return customers; 
      } 
     } 
    } 

    //model 
    public class Customer 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public DateTime HireDate { get; set; } 
    } 
} 
+0

Grazie Edward, stavo lottando con un problema simile - cercando di esporre il mio modello di visualizzazione finestra principale all'interno di un modello di dati e questo lo ha risolto perfettamente. Complimenti a te stesso, e Laurent se mai leggerà questo :) – si618

0

Se si desidera che Blend e Visual Studio visualizzino ciò che il datacontext ha solo in modalità progettazione, è possibile definirlo con le opzioni di debug nella pagina. Per esempio, la mia pagina (in code-behind) lega il suo contesto dati a MainVM nel mio spazio client WP8TestBed, informando quelle informazioni sugli attributi della pagina principale come d: DataContext, è usato solo in fase di progettazione (posso associarlo usando le procedure guidate) e inoltre non crea una nuova istanza del modello di visualizzazione durante il runtime.

Ecco l'esempio, tutti questi spazi dei nomi sono necessari (d, mc e il locale che è dove abita il mio ViewModel (MainVM)):

<phone:PhoneApplicationPage 
x:Class="WP8TestBed.MainPage" 
... 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:local="clr-namespace:WP8TestBed" 
mc:Ignorable="d" 
Name="Primary" 
d:DataContext="{d:DesignInstance local:MainVM}"> 
Problemi correlati