2012-06-07 178 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