Observablecollection <T>в списке не обновляется - PullRequest
0 голосов
/ 25 сентября 2011

У меня есть список Silverlight Listbox, связанный с Observablecollection, который отображается нормально (в первый раз), но когда я пытаюсь обновить его с помощью кода, изменение не отражается в пользовательском интерфейсе.Я использовал шаблон MVVM.Pl посмотри и на view и viewmodel.

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

Ответы [ 2 ]

1 голос
/ 03 октября 2011

Получил подсказку из этого поста Stackoverflow

В основном мне нужно использовать Datacontext с контролем Listbox (даже после установки Datacontext на уровне UserControl) .Единственная строка, которая требует изменения:

<ListBox x:Name="lstBox" ItemsSource="{Binding Users}" DataContext="{StaticResource viewModelKey}"  Width="750" Background="AliceBlue">
1 голос
/ 26 сентября 2011

Во-первых, вы должны избегать размещения свойства коллекции доступным для записи.IE, замените этот код:

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

этим кодом:

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

    }

Затем, когда вы добавляете элемент в коллекцию, вам не нужно сообщать, что коллекция изменилась(свойство коллекции само по себе не изменилось), но это ответственность самой коллекции (через INotifyCollectionChanged):

Итак, метод "onclick" может быть просто таким:

Наконец, я бы заменил объявление ListBox.ItemsSource этим, поскольку два пути не требуются:

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