我正在研究 WP8.1 并且我发现了我的列表框的意外行为 - 为了更容易重现我将代码放在这里。该问题同时出现在设备和模拟器上。
我有一个绑定到 ObservableCollection 的列表框,它在按钮单击时充满了项目:
public sealed partial class MainPage : Page
{
List<string> populationOfItems = new List<string>();
ObservableCollection<string> itemsToView = new ObservableCollection<string>();
public MainPage()
{
this.InitializeComponent();
second.Click += second_Click;
myList.ItemsSource = itemsToView;
// populate list of items to be copied
for (int i = 0; i < 6; i++) populationOfItems.Add("Item " + i.ToString());
BottomAppBar = new CommandBar();
}
private async void second_Click(object sender, RoutedEventArgs e)
{
itemsToView.Clear();
await PopulateList();
}
private async Task PopulateList()
{
await Task.Delay(100); // without this line code seems to work ok
itemsToView.Add("FIRSTELEMENT"); // add first differet element
foreach (var item in populationOfItems)
itemsToView.Add(item);
}
}
我第一次填写列表时,一切都很好(图 1)。但是当我第二次按下按钮时,我可以看到元素不是来自第一个而是来自第二个(图 2)。好的 - 它在上面,但是我可以滚动到它,当我按住手指(鼠标)时,我可以滚动列表并看到它存在,但是当我停止滚动列表时隐藏(滚动到第二个元素)第一个元素。此外,当您选择任何项目时 - 当您按住手指时,列表似乎看起来不错(图 3),当您释放它时,它会再次隐藏第一个元素。当您向上/向下移动列表几次时,它会修复并正常工作。
重现问题的方法:
- 单击第二个按钮一次 - 填写列表
- 向下滚动列表,以便隐藏第一个元素(这很重要)
- 再次按下第二个按钮
- 尝试向上滚动列表并查看第一个元素,松开手指
图1
图2
图3
问题似乎与异步任务有关(这就是为什么我也将这个问题标记为异步) - 没有该行await Task.Delay(100);
,代码似乎可以正常工作。
有谁知道可能出了什么问题?
编辑- 其他一些尝试
我也尝试通过 运行填充过程Dispatcher
,但没有成功 - 存在问题。
我还尝试填充一个临时List
(不是 ObservableCollection),并在从返回后async Task
填充 ObservableCollection - 问题仍然存在。
List<string> temporaryList = new List<string>();
private async Task PopulateList()
{
await Task.Delay(100); // without this line code seems to work ok
temporaryList.Clear();
temporaryList.Add("FIRSTELEMENT"); // add first differet element
foreach (var item in populationOfItems)
temporaryList.Add(item);
}
private async void second_Click(object sender, RoutedEventArgs e)
{
itemsToView.Clear();
await PopulateList();
foreach (var item in temporaryList)
itemsToView.Add(item);
}
编辑 2 - 在 acync 任务中创建的 returnig 列表也没有多大帮助:
private async void second_Click(object sender, RoutedEventArgs e)
{
itemsToView.Clear();
var items = await PopulateList();
foreach (var item in items)
itemsToView.Add(item);
}
private async Task<IEnumerable<string>> PopulateList()
{
await Task.Delay(100); // without this line code seems to work ok
List<string> temporaryList = new List<string>();
temporaryList.Add("FIRSTELEMENT"); // add first differet element
foreach (var item in populationOfItems)
temporaryList.Add(item);
return temporaryList;
}
编辑 3 - 因为我检查了在 Windows Phone 8.1 Silverlight 下运行的相同代码,所以没有问题。