【问题标题】:UWP ListView not loading itemsUWP ListView 未加载项目
【发布时间】:2016-03-20 14:21:20
【问题描述】:

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

下面是我的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; }
    }

我已经为你们提到了cmets中的关键点。 任何帮助将不胜感激,非常感谢..

【问题讨论】:

    标签: listview win-universal-app itemsource


    【解决方案1】:

    在您的代码中,您似乎绑定到一个可观察的视频文件集合。在添加项目之前不要将其设置为新的。如果集合已经绑定,这将破坏您的绑定。改为清除列表中的所有项目

    【讨论】:

      【解决方案2】:

      所以,您的页面没有实现InotifyPropertyChanged,您可以通过两种方式修复它:

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

      【讨论】:

      • 非常感谢,这也帮助我理解了问题,我对此还有一个问题,如何访问非静态绑定属性 public 'ObservableCollection VideoFiles { get;放; }' 在我的 Page 类之外?
      【解决方案3】:

      您只监听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 时,它会破坏绑定,您将不会收到任何有关内容已更改的进一步通知。

      【讨论】:

      • 我对此还有另一个问题,如何访问非静态绑定属性 public 'ObservableCollection VideoFiles { get;放; }' 在我的 Page 类之外?
      • 您需要以某种方式保留对页面的引用。但我猜你想从另一个页面(或其他一些操作)将项目添加到集合中。最好的方法是使用某种类来处理数据源并且在整个应用程序中都可用。例如,它可能是一个单例
      • 我不明白你到底在提议什么,你能用一些代码澄清一下吗?谢谢。 P.S:我尝试制作一个静态公共财产并将该私人收藏分配给它。然后我对其进行了更改,但更改仅发生在该静态属性中,并且我的 ListView 项目没有被更新。 P.S:公共静态属性在整个应用程序中都可用
      • 不确定 x:Bind 是否适用于静态属性,但这可能是您的问题。你可以看看这个例子:codepaste.net/ddtff5它应该适用于你的情况
      猜你喜欢
      • 2017-12-11
      • 2019-01-15
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多