0

我正在WP8.1上工作,我发现我的Listbox的横行为 - 使其更容易重现我已经把the code here。设备和模拟器都会出现此问题。Listbox - 无法选择填充后的第一个元素ItemsSource

我已经被绑定到的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); 
    } 
} 

我第一次填充列表,寄托都是确定的(图一)。但是当我第二次按下按钮时,我可以看到不是从第一个而是从第二个(图2)的元素。好的 - 它在上面,但我可以滚动到它,当我握住我的手指(鼠标)我可以滚动列表并看到它存在,但是当我停止滚动列表隐藏(滚动到第二个元素)第一个元件。另外,当您选择任何项目时 - 当您握住您的手指时,列表似乎看起来很好(图3),当您释放它时,会再次隐藏第一个元素。当您上下移动列表几次时,它会修复并正常工作。

重现该问题的方式:

  • 点击scond按钮一次 - 填充列表
  • 滚动列表下来,让你躲的第一要素(这是很重要的
  • 再次点击第二个按钮
  • 尝试向上滚动列表并查看第一个元素,释放手指

Pic.1 enter image description here

Pic.2 enter image description here

Pic.3 enter image description here

这个问题似乎与异步任务(这就是为什么我还标记了这个问题异步)关注 - 没有行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的工作没有问题。

回答

0

你不应该混合UI与数据检索处理,因为它们现在发生的同时。

也知道,当你调用await PopulateList()执行流程回到UI线程,并准备接受点击和火灾click事件。

试试这个:

private async void second_Click(object sender, RoutedEventArgs e) 
{ 
    // UI thread 
    var items = await PopulateListAsync(); // -> return to UI thread 
    // back to UI thread 
    itemsToView.Clear(); 
    itemsToView.Add("FIRSTELEMENT"); // add first differet element 
    foreach (var item in items) 
    { 
     itemsToView.Add(item); 
    } 
} 

private async Task<IEnumerable<string>> PopulateListAsync() 
{ 
    // caller thread - UI thread 
    await Task.Delay(100) 
     .ConfigureAwait(continueOnCapturedContext: false); 
    // some other thread 
    return populationOfItems; 
} 

您可能需要阅读此:

编辑:

我相信这表明你正在尝试做什么。我为您再次添加了一些延迟,以便在手机上查看它。

MainPage.xaml中

<phone:PhoneApplicationPage 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    x:Class="PhoneApp1.MainPage" 
    mc:Ignorable="d" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    SupportedOrientations="Portrait" Orientation="Portrait" 
    shell:SystemTray.IsVisible="True"> 

    <Grid x:Name="LayoutRoot" Background="Transparent"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 

     <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> 
      <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/> 
      <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> 
     </StackPanel> 

     <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="*"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <phone:LongListSelector x:Name="List" HorizontalAlignment="Stretch" Margin="0" VerticalAlignment="Stretch" ItemsSource="{Binding}" LayoutMode="List"> 
       <phone:LongListSelector.ItemTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding}" Style="{StaticResource PhoneTextExtraLargeStyle}" /> 
        </DataTemplate> 
       </phone:LongListSelector.ItemTemplate> 
      </phone:LongListSelector> 
      <Button Content="Button" Margin="0" Grid.Row="1" Click="Button_Click" x:Name="Button1"/> 

     </Grid> 
    </Grid> 

</phone:PhoneApplicationPage> 

MainPage.xaml.cs中

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Threading.Tasks; 
using System.Windows; 
using Microsoft.Phone.Controls; 

namespace PhoneApp1 
{ 
    public partial class MainPage : PhoneApplicationPage 
    { 
     private List<string> populationOfItems = new List<string> 
     { 
      "one", 
      "two", 
      "three", 
      "four", 
      "five" 
     }; 
     private ObservableCollection<string> itemsToView = new ObservableCollection<string>(); 

     public MainPage() 
     { 
      InitializeComponent(); 
      this.DataContext = this.itemsToView; 
     } 

     private async void Button_Click(object sender, RoutedEventArgs e) 
     { 
      this.Button1.IsEnabled = false; 
      var items = await PopulateListAsync(); 
      itemsToView.Clear(); 
      await Task.Delay(100); 
      itemsToView.Add("FIRSTELEMENT"); 
      foreach (var item in items) 
      { 
       await Task.Delay(10); 
       itemsToView.Add(item); 
      } 
      this.Button1.IsEnabled = true; 
     } 
     private async Task<IEnumerable<string>> PopulateListAsync() 
     { 
      await Task.Delay(100) 
       .ConfigureAwait(continueOnCapturedContext: false); 
      return populationOfItems; 
     } 
    } 
} 
+0

谢谢你的答案。我知道你说过的话。这是我的第一个想法,它可能是关注“其他线程” - 所以我想通过'Dispatcher'运行填充过程(如果你已经下载了我的代码,那么你应该会看到一个与调度第二种方法)。没什么帮助。另请参阅我的编辑问题 - 我也尝试通过单独的临时列表与UI没有连接=没有任何帮助。至于我这个问题似乎是与Listbox本身,也许它的动画 - 但我不知道 - 也许我做错了什么。 – Romasz

+0

您是否尝试过我推荐的方法? –

+0

是的,我已经试过 - 您的例子只是返回一个引用,请列出不被修改(我需要内异步任务修改它 - 这是它是为创建)。我遵循你的建议(见我的第二次编辑),但问题仍然存在。你有什么想法吗? – Romasz

相关问题