我在将列表框中的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会丢失其选定的项目。 更糟糕的是,它只发生每一次按钮点击,当我再次尝试按下按钮然后我得到所需的行为,然后行为再次出错等等。
有人可以解释幕后发生的事情吗?
谢谢
答案 0 :(得分:1)
在LoadNewList
方法中,您要为Names
创建一个新集合:
Names = new ObservableCollection<string>() { "New Daniel", "New James", "New Colin", "New Bruno", "Iza" };
这样做会破坏您现有的绑定。
尝试添加/删除/清空集合:
Names.Clear();
Names.Add("New Daniel");
...