2012-04-09 120 views
2

我正在嘗試使用WPF MVVM。我在XAML簡單的WPF MVVM綁定問題

<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> 

寫下面的代碼我有一個MenuViewModel與性能MenuHeaderMenuItems。我在運行時在兩個屬性中都獲得了值。前者綁定到文本TextBlock,後者綁定到ListBox的ItemSource。但是當我運行該解決方案時,TextBlock和ListBox是空的。

編輯:視圖模型準則

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"); 
      } 

     } 
    } 

在此先感謝。

+1

您是否在視圖模型上實現了'INotifyPropertyChanged'? – ChrisF 2012-04-09 11:23:19

+0

發佈ViewModel的代碼 – 2012-04-09 11:23:45

+1

您是否將視圖的數據上下文設置爲必需的視圖模型? – 2012-04-09 11:29:14

回答

3

您正在使用ViewModel的默認構造函數在XAML中創建ViewModel,該構造函數不執行任何操作。你所有的人口代碼都在非默認的構造函數中,這個構造函數永遠不會被調用。

更常用的方法是在代碼中創建ViewModel,並將其注入到視圖中,或者明確使用View.DataContext = ViewModel,或者非常簡單地使用DataTemplate。

+0

我同意,我不需要默認構造函數,但是當我從xaml分配datacontext時,編譯器說'沒有默認構造函數'。我會嘗試注入viewmodel並刪除默認的構造函數。 – Marshal 2012-04-09 11:46:21

+1

是的,這是問題,我從XAML和默認構造函數中刪除了datacontext賦值,並且它像魅力一樣工作。謝謝 – Marshal 2012-04-09 11:48:51

1

我想你必須觸發OnPropertyChanged事件。我不確定您是否使用MVVM庫(因爲您從ViewModelBase繼承,例如可能使用MVVM Light),它們將OnPropertyChanged包裝在RaisePropertyChanged事件處理程序中。 觸發事件將通知WPF更新UI。

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