2011-09-25 31 views
0

我有一個綁定到Observablecollection的Silverlight列表框,它顯示出很好(第一次),但是當我嘗試通過後面的代碼更新它時,更改不反映在UI中。我使用了MVVM模式。 Pl有一個看,在視圖和viewmodel。Observablecollection <T>在Listbox中沒有更新

<UserControl x:Class="GridOperations.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:GridOperations.ViewModel" 
    mc:Ignorable="d" 
    d:DesignHeight="700" d:DesignWidth="700"> 
    <UserControl.DataContext> 
     <local:ShowUserListViewModel/> 
    </UserControl.DataContext> 
    <UserControl.Resources> 
     <local:ShowUserListViewModel x:Key="viewModelKey"/> 
    </UserControl.Resources> 

    <Grid x:Name="LayoutRoot" Background="White"> 

     <ListBox VerticalAlignment="Top" Margin="0,20,0,0" x:Name="lstBox" ItemsSource="{Binding UserList}" Width="700" Height="150" Background="AliceBlue"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="300"/> 
          <ColumnDefinition Width="100"/> 
          <ColumnDefinition Width="100"/> 
          <ColumnDefinition Width="100"/> 
         </Grid.ColumnDefinitions> 
         <TextBlock Margin="30,0,0,0" Text="{Binding UserId}" HorizontalAlignment="Left"/> 
         <TextBlock Margin="30,0,0,0" Text="{Binding Path=UserName, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Left"/> 
         <Button Margin="30,0,0,0" Grid.Column="2" Content="Edit" Height="20" HorizontalAlignment="Left" Command="{Binding Source={StaticResource viewModelKey}, Path=UpdateUserCommand}" /> 
         <Button Margin="10,0,0,0" Grid.Column="3" Content="Del" Height="20" HorizontalAlignment="Left" /> 
        </Grid> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 

    </Grid> 
</UserControl> 


    public class ShowUserListViewModel : INotifyPropertyChanged 
     { 
      public ShowUserListViewModel() 
      { 
       mUserList = new ObservableCollection<User>(); 
       mUserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "testuser1", IsAdmin = true }); 
       mUserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "testuser2", IsAdmin = true }); 

       this.UpdateUserCommand = new DelegateCommand(this.UpdateUser); 

      } 

      public ICommand UpdateUserCommand { get; private set; } 

      private ObservableCollection<User> mUserList; 
      public ObservableCollection<User> UserList 
      { 
       get 
       { 
        return mUserList; 
       } 
      } 

      public event PropertyChangedEventHandler PropertyChanged; 

      private void UpdateUser() 
      { 
       this.UserList.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "test", IsAdmin = false });    
      } 
     } 
+0

那麼代碼在哪裏呢? – arviman

+0

請顯示您的XAML和代碼隱藏。 –

+0

我想添加。 Stackoverflow不會讓我粘貼大量的代碼,而不會說「請解釋代碼場景...」,並阻止我添加代碼行。 – Subhasis

回答

1

這個職位Stackoverflow

基本上我需要使用的DataContext用得到了暗示列表框控件(甚至在將Datacontext設置爲UserControl級別後)。唯一需要更改的行是:

<ListBox x:Name="lstBox" ItemsSource="{Binding Users}" DataContext="{StaticResource viewModelKey}" Width="750" Background="AliceBlue"> 
1

首先,您應該避免將集合屬性設置爲可寫。這段代碼

private ObservableCollection<User> mUsers = new ObservableCollection<User>(); 
    public ObservableCollection<User> Users 
    { 
     get 
     { 
      return mUsers; 
     } 
     set 
     { 
      mUsers = value; 
      RaisePropertyChangedEvent("Users"); 
     } 
    } 

:IE,將這段代碼然後

private ObservableCollection<User> mUsers = new ObservableCollection<User>(); 
    public ObservableCollection<User> Users 
    { 
     get 
     { 
      return mUsers; 
     } 

    } 

,當你添加一個項目到集合中,你不必告訴收集已經改變(集合屬性本身並沒有改變),但它是集合本身(通過INotifyCollectionChanged)的責任:

因此,「點擊」的方法可以簡單地這樣的:

private void OnClick(User userInstanceToEdit) 
    { 
     this.Users.Add(new User() { UserId = Guid.NewGuid().ToString(), UserName = "test", IsAdmin = false });   

    } 

最後,我想這一個替換ListBox.ItemsSource聲明,因爲兩個方面不要求:

<ListBox x:Name="lstBox" ItemsSource="{Binding Users}"