0

私の問題を最も簡単な方法で説明します。私はリストビューとグリッドビューの両方とバインディングを長い間扱ってきましたが、今は説明のつかない問題を抱えているので、本当に助けが必要です.

以下は私のリストビューの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; }
    }

あなたへのコメントで重要なポイントについて言及しました。 どんな助けでも大歓迎です、どうもありがとう..

4

3 に答える 3

1

あなたのコードでは、監視可能なコレクションのビデオファイルにバインドされているようです。項目を追加する前に new に設定しないでください。コレクションが既にバインドされている場合、これによりバインドが解除されます。代わりに、リストからすべての項目を消去します

于 2016-03-20T14:53:04.157 に答える
1

したがって、あなたのページは を実装していませんInotifyPropertyChanged。次の 2 つの方法で修正できます。

  1. VideoFilesコストラクタでコレクションを初期化すると、すべてが機能します。

  2. INotifyPropertyChangedもう 1 つの方法は、インターフェイスを実装することです。ちなみに、デフォルトのx:Bindモードは ですので、このステップでは に変更するOneTime必要があります。ModeOneWay

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}">
于 2016-03-20T14:57:37.080 に答える
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それに割り当てると、バインドが解除され、コンテンツが変更されたという通知はそれ以上受信されなくなります。

于 2016-03-20T14:58:38.173 に答える