2016-03-20 132 views
0

我會用最簡單的方式解釋我的問題。 我一直在處理listview和gridview和綁定很長一段時間,但現在我有一個無法解釋的問題,所以我真的需要一些幫助。UWP ListView not loading items

以下是我的listview的xaml代碼。

<ListView Name="OtherVideosList" ItemsSource="{x:Bind VideoFiles}" SelectionChanged="OtherVideosList_SelectionChanged"> 
    <ListView.ItemTemplate> 
     <DataTemplate x:DataType="data:VideoFile"> 
      <StackPanel Orientation="Horizontal"> 
       <Image Source="{x:Bind Thumbnail}"/> 
       <StackPanel> 
        <TextBlock Text="{x:Bind FileName}"/> 
        <TextBlock Text="{x:Bind Duration}"/> 
       </StackPanel> 
      </StackPanel> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

我綁定到的ObservableCollection下面 是它的數據類型類。

public class VideoFile 
{ 
    public string FileName { get; set; } 
    public string Duration { get; set; } 
    public StorageFile File { get; set; } 
    public BitmapImage Thumbnail { get; set; } 
} 

使用這個類,我創建的項目源

public ObservableCollection<VideoFile> VideoFiles { get; set; } 

我用一個按鈕來打開多個文件,然後把他們的項目源,後來發揮他們的媒體元素上。下面是事件處理程序的代碼。

private async void OpenClick(object sender, RoutedEventArgs e) 
    { 
     try 
     { 
      var p = new FileOpenPicker(); 
      foreach (var item in videoTypes) 
      { 
       p.FileTypeFilter.Add(item); 
      } 
      //Curentplayingfiles is IReadOnlyList<StorageFiles> 
      CurrentlyPlayingFiles = await p.PickMultipleFilesAsync(); 
      if (CurrentlyPlayingFiles.Count != 0) 
      { 
       if (CurrentlyPlayingFiles.Count == 1) 
       { //this if block works absolutely fine 
        CurrentlyPlayingFile = CurrentlyPlayingFiles[0]; 
        var s = await CurrentlyPlayingFile.OpenReadAsync(); 
        ME.SetSource(s, CurrentlyPlayingFile.ContentType); 
       } 
       else 
       { 
        VideoFiles = new ObservableCollection<VideoFile>(); 
        foreach (var file in CurrentlyPlayingFiles) 
        { 
         //Thumbnail and GetDuration are my own static methods to get thumbnail 
         //and duration property of the file respectively 
         VideoFiles.Add(new VideoFile { Thumbnail = await Thumbnail(file), Duration = await GetDuration(file), File = file, FileName = file.DisplayName }); 
        } 
        //exception occurs on this very line below, because here OtherVideosList has zero items. 
        OtherVideosList.SelectedIndex = 0; 
       } 

      } 

     } 
     catch (Exception s){ var dr = s.Message; } 
    } 

我已經在你的評論中提到了關鍵點guyx。 任何幫助將不勝感激,非常感謝..

回答

1

它看起來像在你的代碼中,你必須可觀察的集合videofiles。在添加項目之前不要將其設置爲新的。如果集合已經綁定,這將破壞綁定。清除所有從列表中的項目,而不是

+0

thankyou先生:) –

1

所以,你的頁面沒有實現InotifyPropertyChanged,您可以在2種方式解決這個問題:

  1. 可以在costructor初始化VideoFiles收集一切都會工作。

  2. 另一種方式,實現INotifyPropertyChanged接口。 順便說一句,默認x:Bind模式是OneTime所以在這一步你需要將Mode更改爲OneWay

C#

public sealed partial class MainPage : Page, INotifyPropertyChanged 
    { 
     private ObservableCollection<VideoFile> _videoFiles { get; set; } 

     public MainPage() 
     { 
      this.InitializeComponent(); 
     } 

     public ObservableCollection<VideoFile> VideoFiles 
     { 
      get 
      { 
       return _videoFiles; 
      } 
      set 
      { 
       if (_videoFiles != value) 
       { 
        _videoFiles = value; 
        RaisePropertyChanged(nameof(VideoFiles)); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void OpenClick(object sender, RoutedEventArgs e) 
     { 
      VideoFiles = new ObservableCollection<VideoFile>(); 
      VideoFiles.Add(new VideoFile() 
      { 
       Duration = "02:00", 
       FileName = "file name", 
       Thumbnail = new BitmapImage(new Uri("http://s.ill.in.ua/i/news/630x373/298/298656.jpg")) 
      }); 

     } 

     private void RaisePropertyChanged(string propertyName) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

XAML:

<ListView Name="OtherVideosList" 
      ItemsSource="{x:Bind VideoFiles, Mode=OneWay}"> 
+0

非常感謝,這也幫助我理解了這個問題,我對此有另外一個問題,我如何訪問非靜態綁定屬性public'ObservableCollection VideoFiles {get;組; }'在我的頁面類之外? –

1

你只監聽CollectionChanged事件,而不是VideoFiles財產本身的變化。 else子句中

// Assuming you're using C# 6. If not, assign it in constructor 
public ObservableCollection<VideoFile> VideoFiles { get; set; } = new ObservableCollection<VideoFile>(); 

然後:試試這個

else 
{ 
    VideoFiles.Clear(); 
    foreach (var file in CurrentlyPlayingFiles) 
    { 
     //Thumbnail and GetDuration are my own static methods to get thumbnail 
     //and duration property of the file respectively 
     VideoFiles.Add(new VideoFile { Thumbnail = await Thumbnail(file), Duration = await GetDuration(file), File = file, FileName = file.DisplayName }); 
    } 
    //exception occurs on this very line below, because here OtherVideosList has zero items. 
    OtherVideosList.SelectedIndex = 0; 
} 

當你分配一個新的集合VideoFiles它打破了約束力,您將不會收到該內容已更改任何進一步的通知。

+0

我對此有另一個問題,我如何訪問非靜態綁定屬性公開'ObservableCollection VideoFiles {get;組; }'在我的頁面類之外? –

+0

您需要以某種方式保留對頁面的引用。但我猜你想從另一個頁面(或其他一些操作)添加項目到集合中。最好的辦法是有一些處理數據源的類,它可以在整個應用程序中使用。它可能是一個單身人士 –

+0

我不明白你的建議,你可以用一些代碼來澄清它嗎?謝謝。 P.S:我嘗試製作一個靜態公共財產並將其分配給它。然後我對它進行了更改,但更改只發生在該靜態屬性中,而我的ListView項目未更新。 P.S:公共靜態屬性在應用程序中可用 –