2012-06-07 80 views
5

我是WPF的新手,並嘗試使用MVVM框架構建示例應用程序。我的應用程序有一個xaml文件,它有一些用於輸入客戶信息的文本框,用於顯示狀態的組合框和一個保存按鈕。所有的數據綁定都通過ViewModel(CustomerViewMode)完成,該模型引用了Model(Customer),其中包含必需的字段及其Getter,setter。 viewModel有一個CustomerList屬性。 單擊保存按鈕時,我想要在ListBox中顯示Customer的FirstName和LastName屬性。這是問題所在。我調試了代碼 (點擊後面代碼中的按鈕事件),我可以看到CustomerList具有包含所有細節的第一個Customer對象,但它沒有顯示在列表框中。我的代碼是: Customer(Model);我的代碼是: Customer(Model);列表框與WPF中的ViewModel綁定

enter code here 
namespace SampleMVVM.Models 
{ 
class Customer : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private String _firstName; 
    private String _lastName; 
    private Address _customerAddress; 


    public String FirstName 
    { 
     get { return _firstName; } 
     set 
     { 
      if (value != _firstName) 
      { 
       _firstName = value; 
       RaisePropertyChanged("FirstName"); 
      } 
     } 
    } 

    public String LastName 
    { 
     get { return _lastName; } 
     set 
     { 
      if (value != _lastName) 
      { 
       _lastName = value; 
       RaisePropertyChanged("LastName"); 
      } 
     } 
    } 

    public Address CustomerAddress 
    { 
     get { return _customerAddress; } 
     set 
     { 
      if (value != _customerAddress) 
      { 
       _customerAddress = value; 
       RaisePropertyChanged("CustomerAddress"); 
      } 
     } 
    } 

    private void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 


} 

}

地址(型號)

namespace SampleMVVM.Models 
{ 
class Address : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private string _addressLine1; 
    private string _addressLine2; 
    private string _city; 
    //private string _selectedState; 
    private string _postalCode; 
    private string _country; 






    public String AddressLine1 
    { 
     get { return _addressLine1; } 
     set 
     { 
      if (value != _addressLine1) 
      { 
       _addressLine1 = value; 
       RaisePropertyChanged(AddressLine1); 
      } 
     } 
    } 

    public String AddressLine2 
    { 
     get { return _addressLine2; } 
     set 
     { 
      if (value != _addressLine2) 
      { 
       _addressLine2 = value; 
       RaisePropertyChanged(AddressLine2); 
      } 
     } 
    } 

    public String City 
    { 
     get { return _city; } 
     set 
     { 
      if (value != _city) 
      { 
       _city = value; 
       RaisePropertyChanged(City); 
      } 
     } 
    } 




    public String PostalCode 
    { 
     get { return _postalCode; } 
     set 
     { 
      if (value != _postalCode) 
      { 
       _postalCode = value; 
       RaisePropertyChanged(PostalCode); 
      } 
     } 
    } 

    public String Country 
    { 
     get { return _country; } 
     set 
     { 
      if (value != _country) 
      { 
       _country = value; 
       RaisePropertyChanged(Country); 
      } 
     } 
    } 

    private void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

}

CustomerViewModel:

namespace SampleMVVM.ViewModels 
{ 
class CustomerViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private Customer _customer; 
    RelayCommand _saveCommand; 
    private List<String> _stateList = new List<string>(); 
    private string _selectedState; 

    private ObservableCollection<Customer> _customerList = new ObservableCollection<Customer>(); 


    //public CustomerViewModel(ObservableCollection<Customer> customers) 
    //{ 
    // _customers = new ListCollectionView(customers); 

    //} 



    public Customer CustomerModel 
    { 
     get { return _customer; } 
     set 
     { 
      if (value != _customer) 
      { 
       _customer = value; 
       RaisePropertyChanged("CustomerModel"); 
      } 
     } 
    } 

    public List<String> StateList 
    { 
     get 
     { 

      return _stateList; 
     } 
     set { _stateList = value; } 

    } 

    public ObservableCollection<Customer> CustomerList 
    { 
     get 
     { 

      return _customerList; 
     } 
     set 
     { 
      if (value != _customerList) 
      { 
       _customerList = value; 
       RaisePropertyChanged("CustomerList"); 
      } 

     } 

    } 


    public CustomerViewModel() 
    { 
     CustomerModel = new Customer 
     { 
      FirstName = "Fred", 
      LastName = "Anders", 

      CustomerAddress = new Address 
      { 
       AddressLine1 = "Northeastern University", 
       AddressLine2 = "360, Huntington Avenue", 
       City = "Boston", 
       PostalCode = "02115", 
       Country = "US", 


      } 
     }; 

     StateList = new List<String> 
     { 
      "Alaska", "Arizona", "California", "Connecticut", "Massachusetts", "New Jersey", "Pennsylvania", "Texas" 
     }; 
     SelectedState = StateList.FirstOrDefault(); 


    } 

    public String SelectedState 
    { 
     get { return _selectedState; } 
     set 
     { 
      if (value != _selectedState) 
      { 
       _selectedState = value; 
       RaisePropertyChanged(SelectedState); 
      } 
     } 
    } 

    private void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

     } 

}

CustomerInfo.xaml(圖)(隱藏類代碼)

<UserControl x:Class="SampleMVVM.Views.CustomerInfo" 
     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:ViewModels="clr-namespace:SampleMVVM.ViewModels"    
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 

<UserControl.DataContext> 
    <ViewModels:CustomerViewModel /> 
</UserControl.DataContext> 



<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 


    <!--Starting label--> 
    <TextBlock FontSize="18" FontFamily="Comic Sans MS" FontWeight="ExtraBlack" 
       Foreground="Navy" 
       Grid.Row="0" HorizontalAlignment="Center"> 
     <TextBlock.Text> 
      Customer Information: 
     </TextBlock.Text> 
    </TextBlock> 

    <TextBlock Text="First name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="1" Width="80px" Height="50px" Margin="40,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.FirstName}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="1" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="fname"/> 

    <TextBlock Text="Last Name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="2" Width="80px" Height="50px" Margin="40,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.LastName}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="2" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="lname"/> 

    <TextBlock Text="Address: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="3" Width="80px" Height="50px" Margin="40,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine1}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="3" Grid.Column="1" Width="160px" Height="20px" Margin="20,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine2}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="4" Grid.Column="1" Width="160px" Height="30px" Margin="20,5,0,0"/> 

    <TextBlock Text="City: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="5" Width="80px" Height="20px" Margin="40,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.CustomerAddress.City}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="5" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/> 

    <TextBlock Text="State: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="6" Width="80px" Height="20px" Margin="40,5,0,0"/> 
    <ComboBox Grid.RowSpan="2" HorizontalAlignment="Left" Name="listOfSates" 
       VerticalAlignment="Top" 
       Grid.Row="6" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" 
       ItemsSource="{Binding Path=StateList}" 
       SelectedItem="{Binding Path=SelectedState}" 
       SelectionChanged="ComboBox_SelectionChanged" 
       > 


    </ComboBox> 

    <TextBlock Text="PostalCode: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="7" Width="80px" Height="20px" Margin="40,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.CustomerAddress.PostalCode}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="7" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/> 

    <TextBlock Text="Country: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Grid.Row="8" Width="80px" Height="20px" Margin="40,5,0,0"/> 
    <TextBox Text="{Binding CustomerModel.CustomerAddress.Country}" Grid.RowSpan="2" HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="8" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/> 

    <Button Content="Save" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" 
      Grid.Row="9" Width="50px" Height="20px" Name="savebtn" Margin="40,5,0,0" 
      Click="savebtn_Click"/> 


    <ListBox Name="cList" ItemsSource="{Binding Path=CustomerList}" 
      HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" Width="200px" Height="300px" Margin="200,5,0,0"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel> 
        <TextBlock Text="{Binding CustomerModel.FirstName}" 
          FontWeight="Bold" Foreground="Navy"/> 
        <TextBlock Text=", " /> 
        <TextBlock Text="{Binding CustomerModel.LastName}" 
          FontWeight="Bold" Foreground="Navy"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

CustomerInfo

namespace SampleMVVM.Views 
{ 
/// <summary> 
/// Interaction logic for CustomerInfo.xaml 
/// </summary> 
public partial class CustomerInfo : UserControl 
{ 
    public CustomerInfo() 
    { 
     InitializeComponent(); 

     //checkvalue(); 
    } 

      private void savebtn_Click(object sender, RoutedEventArgs e) 
    { 
     ////Customer c = new Customer(); 
     ////c.FirstName = fname.Text; 
     ////c.LastName = lname.Text; 
     //CustomerViewModel cvm = new CustomerViewModel(); 
     //cvm.CustomerModel.FirstName = fname.Text; 
     //cvm.CustomerModel.LastName = lname.Text; 
     //List<CustomerViewModel> customerList = new List<CustomerViewModel>(); 
     //customerList.Add(cvm); 
     var viewModel = DataContext as CustomerViewModel; 


     if (viewModel != null) 
     { 

      //viewModel.ShowCustomerInfo(); 
      String strfname = viewModel.CustomerModel.FirstName; 
      String strname = viewModel.CustomerModel.LastName; 

      viewModel.CustomerList.Add(viewModel.CustomerModel); 
      String str1 = viewModel.CustomerList.FirstOrDefault().FirstName; 
      int i = viewModel.CustomerList.Count(); 
      //cList.ItemsSource = viewModel.CustomerList; 

     } 

    } 

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     CustomerViewModel cvm = new CustomerViewModel(); 
     cvm.SelectedState = listOfSates.SelectedItem.ToString(); 
    } 




} 

}

我只是不能明白我要去哪裏錯了......有人請幫助

回答

2

而對於正確的ListBox.ItemTemplate結合:

<TextBlock Text="{Binding FirstName}" 
      FontWeight="Bold" Foreground="Navy"/> 
<TextBlock Text="{Binding LastName}" 
      FontWeight="Bold" Foreground="Navy"/> 

的的ListBoxItemDataContext已經是一個客戶。

+0

非常感謝你:))我改變了列表框中的綁定,它工作:) – user1318369

1

你的問題是在這行代碼:

RaisePropertyChanged("CustomerList"); 

它不適用於收集添加/刪除事件。看看ObservableCollection and Item PropertyChanged

請記住,在MVVM中,代碼背後不應該有太多的代碼(如果有的話)。考慮使用命令。

3

您只在代碼中(在Customer View Model構造函數中)創建一個CustomerModel對象的新實例。所以你不斷地更新同一個客戶對象而不是創建一個新對象。

在您單擊處理程序結束時,你應該做一個

viewModel.CustomerModel = new Customer(); 

無論其

不是有你應該有一個ICommand您的視圖模型添加一個新客戶的點擊處理程序。然後你應該將你的按鈕命令綁定到視圖模型中的ICommand。

+0

同意,但應該是'viewModel.CustomerModel = new Customer();' – LPL

2

您綁定了不是walid的CustomerLIst.FirstName,因爲innterconent會檢查列表框itemssource中的屬性customerlist。並且因爲它不是它們的話,它會引發一個沉默的錯誤,但是不會顯示到GUI中,你需要做的只是提供像名字和姓氏這樣的屬性名稱。

除了你在列表框中的綁定,其他的東西都可以。只需替換你的列表框綁定,如下所示。

<TextBlock Grid.Row="0" 
        Grid.Column="2" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center" 
        Text="List of Customers" /> 
     <ListBox Name="cList" 
       Grid.Row="1" 
       Grid.RowSpan="8" 
       Grid.Column="2" 
       ItemsSource="{Binding CustomerList}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel> 
         <TextBlock FontWeight="Bold" 
            Foreground="Black" 
            Text="{Binding FirstName}" /> 
         <TextBlock Text=", " /> 
         <TextBlock FontWeight="Bold" 
            Foreground="Black" 
            Text="{Binding LastName}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
     <TextBlock Grid.Row="10" 
        Grid.Column="2" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center" 
        Text="{Binding CustomerList.Count, 
            StringFormat='Total Customers, ={0}'}" /> 

更好地承擔事件的責任。

+0

非常感謝Jodha :)你的代碼工作:) – user1318369