zapico
zapico

Reputation: 2396

ListBox SelectedItem not working

I'm trying to load a list of objects as grids with several data and I've selected ListBox for it as you can see here:

<ListBox ItemsSource="{Binding People, Mode=TwoWay}" SelectedItem="{Binding Person, Mode=TwoWay}" >
  <ListBox.ItemContainerStyle>
     <Style TargetType="ListBoxItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
     </Style>
  </ListBox.ItemContainerStyle>
  <ListBox.ItemTemplate>
     <DataTemplate>
         <Grid>
             <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="200"></ColumnDefinition>
                  <ColumnDefinition Width="50"></ColumnDefinition>
                  <ColumnDefinition Width="30"></ColumnDefinition>
                  <ColumnDefinition Width="50"></ColumnDefinition>
                  <ColumnDefinition Width="20"></ColumnDefinition>
             </Grid.ColumnDefinitions>
             <TextBlock VerticalAlignment="Center" Text="{Binding name}" Grid.Column="0" TextAlignment="Right"></TextBlock>
             <TextBox Grid.Column="1" Margin="5,0,0,0" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="{Binding age}"></TextBox>
             <TextBlock Grid.Column="2" Text="yo" VerticalAlignment="Center" Margin="5,0,0,0"></TextBlock>
             <TextBox Grid.Column="3" Margin="5,0,0,0" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="{Binding baremo}"></TextBox>
             <TextBlock Grid.Column="4" Text="€" VerticalAlignment="Center" Margin="5,0,0,0"></TextBlock>
         </Grid>
    </DataTemplate>
 </ListBox.ItemTemplate>

When I load data into People ObservableCollection everything goes right and it is shown perfectly.

The first time I select a Person, it works and it sets the property value in the VM.

The problem comes the second time I select a different "Person". The property doesn't change and... every time I select a different one, it takes a little longer (after 10 ó 20 it is MUCH LONGER).

Here is my ViewModel code:

#region People
        public const string PeoplePropertyName = "People";

        private ObservableCollection<Player> _People;

        public ObservableCollection<Player> People
        {
            get
            {
                return _People;
            }

            set
            {
                _People = value;
                RaisePropertyChanged(People);
            }
        }
        #endregion

        #region Person
        public const string PersonPropertyName = "Person";

        private Player _Person;

        public Player Person
        {
            get
            {
                return _Person;
            }

            set
            {
                _Person = value;
                RaisePropertyChanged(PersonPropertyName);
            }
        }
        #endregion

And I'm loading the People list like this:

void LoadPeople(GetPlayersEventArgs e)
{
     if (this.People == null) this.People = new ObservableCollection<Player>();

        foreach (Player Person in e.Result)
        {
            Player newPerson = new Player();
            ...
            this.People.Add(newPerson);
        }

        this.SetUnBusy();
}

Am I missing anything?? Thanks in advance.

After @Ryan question I've seen everytime I try to select another value, I get a lot of:

A first chance exception of type 'System.InvalidCastException' occurred in Solution

Upvotes: 3

Views: 2012

Answers (2)

Thelonias
Thelonias

Reputation: 2935

I'd recommend turning on the feature that will break when a CLR exception is thrown. If you're using Visual Studio 2010 or 2012, go to Debug -> Exceptions (or Ctrl-E,D by default) and under "Common Language Runtime Exceptions" make sure "Thrown" is checked on. Then re-run your solution and see if anything breaks.

Then you'll see the problem in your Person object ;)

Upvotes: 1

Ed Chapel
Ed Chapel

Reputation: 6942

From what you've shared the implementation of the Person property is good. There are a few things I would recommend.

As vinod8812 suggests, change the binding mode to OneWay, or remove it as OneWay is the default:

<ListBox ItemsSource="{Binding People}" SelectedItem="{Binding Person, Mode=TwoWay}" >

Change the sequence of populating the ObservableCollection<Player> in your ViewModel:

public class ViewModel
{
    private readonly ObservableCollection<Player>();

    public ViewModel()
    {
        _People = new ObservableCollection<Player>();
    }

    public ObservableCollection<Player> People
    {
        get
        {
            return _People;
        }
    }
    /* rest of class */
}

Finally, clear out the _People collection before populating it. Otherwise you may just be adding duplicates:

void LoadPeople(GetPlayersEventArgs e)
{
    _People.Clear();

    foreach (Player Person in e.Result)
    {
        Player newPerson = new Player();
        ...
        this.People.Add(newPerson);
    }

    this.SetUnBusy();
}

Is there anything that you know is bound to the INotifyPropertyChanged.PropertyChanged event on your ViewModel? It is not clear from the code you have shared exactly what could be causing the app to slow down.

Upvotes: 2

Related Questions