2012-04-09 7 views
2

Je suis en train de tester WPF MVVM. J'ai écrit code suivant dans XAMLUn problème de liaison MVMP simple Wpf

<UserControl x:Class="Accounting.Menu" 
      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" 
      xmlns:local="clr-namespace:Accounting" 
      mc:Ignorable="d" 
      d:DesignHeight="105" d:DesignWidth="300"> 
    <UserControl.DataContext> 
     <local:MenuViewModel/> 
    </UserControl.DataContext> 
    <StackPanel> 
     <StackPanel> 
       <TextBlock Text="{Binding Path=MenuHeader}"/> 
     </StackPanel> 
     <ListBox ItemsSource="{Binding Path=MenuItems}" Height="70"/>    
    </StackPanel>  
</UserControl> 

J'ai un MenuViewModel avec des propriétés MenuHeader et MenuItems. Je reçois des valeurs dans les deux propriétés pendant l'exécution. L'ancien est lié au texte de TextBlock et le dernier à ItemSource de ListBox. Mais lorsque je lance la solution, TextBlock et ListBox sont vides.

Edit: Code de ViewModel

public class MenuViewModel: ViewModelBase 
    { 
     AccountingDataClassesDataContext db; 

     private string _menuType; 
     public string MenuHeader { get; set; } 
     public ObservableCollection<string> MenuItems { get; set; } 

     public MenuViewModel() 
     { 

     } 

     public MenuViewModel(string menuType) 
     { 
      this._menuType = menuType; 
      db = new AccountingDataClassesDataContext(); 
      if (menuType == "Vouchers") 
      { 
       var items = db.Vouchers.OrderBy(t => t.VoucherName).Select(v => v.VoucherName).ToList<string>(); 

       if (items.Any()) 
       { 
        MenuItems = new ObservableCollection<string>(items); 
        MenuHeader = "Vouchers"; 
       } 
      } 
      else 
      { 
       System.Windows.MessageBox.Show("Menu not found"); 
      } 

     } 
    } 

Merci à l'avance.

+1

Avez-vous implémenté 'INotifyPropertyChanged' sur votre modèle de vue? – ChrisF

+0

Postez le code de votre ViewModel –

+1

Avez-vous défini le contexte de données de votre vue comme étant le modèle requis? –

Répondre

3

Vous créez votre ViewModel dans le code XAML en utilisant le constructeur par défaut de votre ViewModel qui ne fait rien. Tout votre code de population est dans le constructeur non-par défaut qui n'est jamais appelé. La manière la plus courante est de créer le ViewModel en code, et de l'injecter dans la vue en utilisant explicitement View.DataContext = ViewModel, ou implicitement en utilisant un DataTemplate.

+0

Je suis d'accord, je n'ai pas besoin de constructeur par défaut, mais quand j'attribue datacontext de xaml, le compilateur dit 'il n'y a pas de constructeur par défaut'. Je vais essayer d'injecter viewmodel et de supprimer le constructeur par défaut. – Marshal

+1

Oui, c'était le problème, j'ai supprimé l'affectation de datacontext de XAML et le constructeur par défaut, et cela fonctionne comme un charme. Merci – Marshal

1

Je pense que vous devez déclencher l'événement OnPropertyChanged. Je ne suis pas sûr si vous utilisez une bibliothèque MVVM (puisque vous héritez de ViewModelBase vous pourriez utiliser MVVM Light par exemple), là ils enveloppent le OnPropertyChanged dans le gestionnaire d'événement RaisePropertyChanged. Le déclenchement de l'événement informera WPF de la mise à jour de l'interface utilisateur.

string m_MenuHeader; 
public string MenuHeader 
{ 
    get 
    { 
     return m_MenuHeader; 
    } 
    set 
    { 
     m_MenuHeader=value; OnPropertyChanged("MenuHeader"); 
    } 
}