2009-05-05 9 views
8

Pour ceux utilisant Expression Blend ainsi que Visual Studio dans vos projets réels, s'il vous plaît aidez-moi à comprendre comment vous utilisez Blend et Visual Studio dans votre développement de tous les jours/tâches de conception, voici un vrai scénario:Comment utiliser Expression Blend pour modifier un DataTemplate créé dans Visual Studio?

J'ai créé l'application WPF simple suivante dans Visual Studio. Il montre une liste d'objets clients avec un DataTemplate qui montre les clients dans des boîtes orange simples.

Je maintenant voulez mettre un peu pizazz dans ce DataTemplate en utilisant Expression Blend.

Je ouvrir le projet dans Expression Blend penser que je vais voir les boîtes orange que je peux changer la couleur, créer une animation que je souris dessus, la redimensionner, etc. Cependant, tous Je vois dans Expression Blend est une boîte complètement vide.

Je comprends:

  • Expression Blend peut ne pas sembler comprendre que mes données provient de la ViewModel et donc ne l'affiche pas. Est-ce une limitation de Blend ou ai-je besoin de changer mon code d'une manière ou d'une autre afin que Blend puisse interpréter quelles données sortiront au moment de l'exécution? J'utilise Expression Blend 3 qui a la capacité de "données d'échantillon". Quelle est la meilleure façon d'utiliser cet exemple de fonctionnalité de données afin que, même s'il ne peut pas interpréter le C# et comprendre quelles données sortiront de la propriété ViewModel pour remplir la Listbox, comment puis-je l'obtenir au moins certaines données factices afin que je puisse manipuler le 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> 

code Derrière:

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

Pourquoi ne mettez-vous pas votre réponse comme une réponse et alors l'accepte moi-même. –

+0

Je le ferai si je me souviens bien, mais il y a des contraintes de temps qui rendent la tâche difficile: il faut attendre 48 réponses avant de répondre à sa propre question et 48 heures avant de l'accepter. –

+0

Eh bien c'est dans les réponses au moins. –

Répondre

7

Je viens de comprendre ceci afin me permettre de répondre à ma propre question. J'ai lu Laurent's Bugnion enlighting article on this et il s'est avéré que je devais juste modifier le code ci-dessus afin que je puisse voir les données de mon ViewModel affichées dans l'interface graphique Expression Blend et pu éditer le DataTemplate dans Blend, l'enregistrer, puis poursuite de l'édition dans Visual Studio. Fondamentalement, les modifications sont les suivantes: (1) retirer l'instruction DataContext du code précédent, (2) ajouter l'espace de noms "local" en XAML, (3) définir un fournisseur de données local en XAML ("TheDataProvider"), (4) lier directement à partir de la ListBox.

Voici le code qui fonctionne dans Expression Blend et Visual Studio en plein:

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> 

code Derrière:

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

Merci Edward, je me débattais avec un problème similaire - en essayant d'exposer mon modèle de vue de la fenêtre principale à l'intérieur d'un gabarit de données et cela l'a résolu parfaitement. Bravo à toi-même, et Laurent s'il lit ça :) – si618

0

Si l'on veut que Blend et Visual Studio voient ce que le datacontext a en mode conception seulement, cela peut être défini avec les options de débogage sur la page. Supposons par exemple que ma page (en code-behind) lie son contexte de données à MainVM dans mon espace natif WP8TestBed, en informant cette information sur les attributs de la page principale comme d: DataContext, elle est seulement utilisée pendant le design (je peux lier en utilisant les assistants) et ne crée pas non plus une nouvelle instance du modèle de vue pendant l'exécution.

Voici l'exemple, tous ces espaces de noms sont nécessaires (d, mc et le local qui est où mon ViewModel (MainVM) vit):

<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}"> 
Questions connexes