使用任务问题时,如何在listBox中修复SelectedItem null

时间:2015-03-19 16:08:26

标签: wpf asynchronous listbox selecteditem

我在将列表框中的selectedItem设置为null时遇到问题。但它每隔一段时间就会这样做,我可以“弄清楚它为什么会发生。它只发生在我尝试使用Task获取某些数据异步时。我创建了一个非常简单的项目来显示确切的问题,我发现很难理解。 所以这是我的xaml

<Window x:Class="AsyncProblem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Orientation="Horizontal">
       <ListBox ItemsSource="{Binding Names}" SelectedItem="{Binding SelectedName}" />
        <Button Click="Button_Click" Content="Reload" Width="50" Height="50" />
    </StackPanel>
</Window>

这是我的viewmodel:

namespace AsyncProblem
{
public class MainWindowViewModel : NotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        Names = new ObservableCollection<string>() { "Name", "Second Name",  "Third Name"};
    }

    private ObservableCollection<string> names;
    public ObservableCollection<string> Names
    {
        get { return names; }
        set
        {
            names = value;
            OnPropertyChanged();
        }
    }

    private string selectedName;
    public string SelectedName
    {
        get { return selectedName; }
        set
        {
            selectedName = value;
            OnPropertyChanged();
        }
    }

    Task loadTask;
    int counter = 0;
    public void LoadNewList()
    {
        counter++;
        loadTask = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(2000);
                Names = new ObservableCollection<string>()
                {
                    string.Format("{0} new name", counter), 
                    string.Format("{0} second new name", counter),
                    string.Format("{0} third new name", counter)
                };
            });
    }
    public void ReselectSelectedName()
    {
        loadTask.ContinueWith(previousTask => SelectedName = Names.LastOrDefault());
    }
    }
}

这是调用代码

public partial class MainWindow : Window
{
    private MainWindowViewModel dataContext;
    public MainWindow()
    {
        InitializeComponent();
        dataContext = new MainWindowViewModel();
        DataContext = dataContext;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        dataContext.LoadNewList();
        dataContext.ReselectSelectedName();
    }
}

现在,当我运行此程序并按下按钮时,如果获取新列表,但它没有设置selectedName。实际上会发生什么,所选名称会更改为iza,然后以某种方式第二次调用selectedname set,其值为null。所以对于coursethe listbox会丢失其选定的项目。 更糟糕的是,它只发生每一次按钮点击,当我再次尝试按下按钮然后我得到所需的行为,然后行为再次出错等等。

有人可以解释幕后发生的事情吗?

谢谢

1 个答案:

答案 0 :(得分:1)

LoadNewList方法中,您要为Names创建一个新集合:

Names = new ObservableCollection<string>() { "New Daniel", "New James", "New Colin", "New Bruno", "Iza" };

这样做会破坏您现有的绑定。

尝试添加/删除/清空集合:

Names.Clear();
Names.Add("New Daniel");
...