ListBox的SelectedItem属性不起作用

3

我正在尝试加载一系列包含多个数据的对象,并将其作为网格显示,我选择了ListBox,如下所示:

<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>

当我将数据加载到People ObservableCollection中时,一切都很顺利,并且完美地显示出来。

第一次选择一个Person时,它可以正常工作并设置VM中的属性值。

问题出现在第二次选择不同的"Person"时。该属性不会改变,而且每次选择不同的人时,需要更长的时间(10或20次后,时间要长得多)。

这是我的ViewModel代码:

#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

我正在这样加载“People”列表:

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

我有所遗漏吗?谢谢提前。

在@Ryan的问题之后,我每次尝试选择另一个值时都会出现很多:

'System.InvalidCastException'类型的第一次机会异常发生在Solution中


LoadPeople 是如何被调用的?是什么导致它被调用的? - Ed Chapel
1
为什么列表框中的ItemsSource属性需要Mode = TwoWay?尝试将其移除。 - vinod8812
1
你的输出窗口中有任何相关信息吗? - Thelonias
1
@zapico 我建议您打开 CLR 异常抛出时自动中断的功能。如果您使用的是 Visual Studio 2010 或 2012,可以前往“调试”->“异常”(默认快捷键为 Ctrl-E,D),在“公共语言运行时异常”下确保已勾选“抛出”。然后重新运行您的解决方案,看看是否有任何异常被触发。 - Thelonias
1
谢谢Ryan!!! 这是因为我的Person对象内部出了问题!!! 请将此评论发布为答案,以便我选择它作为正确的答案;-)。再次感谢。 - zapico
显示剩余3条评论
2个回答

2

根据您提供的信息,Person属性的实现很好。但我有几个建议。

正如vinod8812建议的那样,将绑定模式更改为OneWay或删除它,因为OneWay是默认值:

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

更改ViewModel中填充ObservableCollection<Player>的顺序:

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

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

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

最后,在填充之前,清空_People集合。否则,您可能会添加重复的内容:

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

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

    this.SetUnBusy();
}

你的ViewModel是否绑定了INotifyPropertyChanged.PropertyChanged事件?从你分享的代码中并不清楚是什么导致了应用程序变慢。


感谢您的回答。 "twoway"模式只是为了看看它是否已经“重新加载”,现在已经被删除了。我认为与propertychanged事件没有任何关联,但奇怪的是:每次我选择不同的内容时,它都会增加。最奇怪的是,第一次选择项目后,绑定的属性被设置,但之后就不会改变了... - zapico

1
我建议打开当CLR异常抛出时会中断的功能。如果您使用的是Visual Studio 2010或2012,请转到调试->异常(默认情况下为Ctrl-E,D),在“公共语言运行时异常”下确保选中“已抛出”。然后重新运行解决方案,看看是否有任何问题。
然后您将在您的Person对象中看到问题;)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接