UWP ListView无法加载项目

时间:2016-03-20 14:21:21

标签: listview win-universal-app itemsource

我将以最简单的方式解释我的问题。 我一直在处理listview和gridview以及绑定很长一段时间,但现在我遇到了一个无法解决的问题,所以我真的需要一些帮助。

以下是我的列表视图的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; }
    }

我已经在你的评论中提到了关键点。 任何帮助都将受到高度赞赏,非常感谢..

3 个答案:

答案 0 :(得分:1)

在您的代码中,您看起来像是一个可观察的集合视频文件。在添加项目之前,请勿将其设置为新的。如果集合已经绑定,这将破坏您的绑定。清除列表中的所有项目

答案 1 :(得分:1)

因此,您的网页未实现InotifyPropertyChanged,您可以通过两种方式修复它:

  1. 您可以在costructor中初始化您的VideoFiles集合,一切都可以正常工作。

  2. 另一种方法是实现INotifyPropertyChanged接口。 顺便说一句,默认x:Bind模式为OneTime,因此在此步骤中您需要将Mode更改为OneWay

  3. 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}">
    

答案 2 :(得分:1)

您只是在监听CollectionChanged个事件而不是VideoFiles属性本身的更改。试试这个:

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

然后在else子句中:

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时,它会破坏绑定,您将不会再收到有关内容已更改的通知。