0
votes

I have a Silverlight Listbox bound to Observablecollection which shows up fine (first time) but when I try to update it through the code behind, the change does not reflect in UI. I have used MVVM pattern . Pl have a look and at view and 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
Please show your XAML and codebehind.Daniel A. White
i am trying to add. Stackoverflow is not letting me paste chunk of code without saying "Please explain the code scenario..." and preventing me from adding lines of code.Subhasis
You should take your code and start cutting it down until it is the smallest possible example that illustrates your problem. Then update your question.ColinE
guys...i have taken your suggestion and narrowed down the problem to a listbox bound a observablecollection (this part works fine) , having a button to edit the collection, but does not shows in the UI. Evrythings shown and explained in the code....can anybody help here...Subhasis

2 Answers

1
votes

Firstly, you should avoid putting a collection property writable. IE, replace this code :

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

by this code :

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

    }

Then, when you add an item to the collection, you don't have to tell the collection has changed (the collection property hasn't changed in itself), but it's the responsibility of the collection itself (via INotifyCollectionChanged) :

So, the "onclick" method can be simply like this:

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

    }

Finally, I would replace the ListBox.ItemsSource declaration with this one, as two ways is not required :

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

Got a hint from this post Stackoverflow

Basically I need to use Datacontext with Listbox control (even after setting the Datacontext at UserControl level). The only line that required change is:

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