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

相關問題