UWP 10 C#. Reading a text file into a List<>

╄→尐↘猪︶ㄣ 提交于 2019-12-06 07:29:17

Try implementing INotifyPropertyChanged and ObservableCollection interfaces that are used to notify clients, typically binding clients, that a property value has changed.

Also use Task to load the data.

Edit:

MainPage.cs.xaml

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading.Tasks;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace TestUWP
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private ObservableCollection<ThreeColumnList> threeColumnLists;

        public ObservableCollection<ThreeColumnList> ThreeColumnLists
        {
            get { return threeColumnLists ?? (threeColumnLists = new ObservableCollection<ThreeColumnList>()); }
            set { threeColumnLists = value; }
        }
        public MainPage()
        {
            this.InitializeComponent();
            LoadData();

        }

        private async void LoadData()
        {
            //you can also change the private threeColumnLists to a static 
            // and do 
            //if(ThreeColumnLists.Count==0) 
            //   ThreeColumnLists = await ThreeColumnListManager.GetListAsync();
            ThreeColumnLists = await ThreeColumnListManager.GetListAsync();
            //can also do
            // await ThreeColumnListManager.readList(ThreeColumnLists);
        }

    }

    public class ThreeColumnList : INotifyPropertyChanged
    {
        private string name = string.Empty;
        public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } }

        private string age = string.Empty;
        public string Age { get { return age; } set { age = value; NotifyPropertyChanged("Age"); } }

        private string job = string.Empty;
        public string Job { get { return job; } set { job = value; NotifyPropertyChanged("Job"); } }

        //PropertyChanged handers
        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    public class ThreeColumnListManager
    {
        public static async Task<ObservableCollection<ThreeColumnList>> GetListAsync()
        {
            var threecolumnlists = new ObservableCollection<ThreeColumnList>();

            //Add a dummy row to present something on screen
            threecolumnlists.Add(new ThreeColumnList { Name = "Name1", Age = "Age1", Job = "Job1" });

            //First working method
            await readList(threecolumnlists);

            //Second Working Method
            //tryAgain(threecolumnlists);

            return threecolumnlists;
        }

        public static async Task readList(ObservableCollection<ThreeColumnList> tcl)
        {
            string _line;
            var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Lists/slplist.txt"));
            using (var inputStream = await file.OpenReadAsync())
            using (var classicStream = inputStream.AsStreamForRead())
            using (var streamReader = new StreamReader(classicStream))
            {
                while (streamReader.Peek() >= 0)
                {
                    Debug.WriteLine("Line");
                    _line = streamReader.ReadLine();
                    //Debug.WriteLine(string.Format("the line is {0}", _line ));
                    string _first = "" + _line.Split('-')[0];
                    string _second = "" + _line.Split('-')[1];
                    string _third = "" + _line.Split('-')[2];

                    tcl.Add(new ThreeColumnList { Name = _first, Age = _second, Job = _third });
                }
            }
        }

        public static async Task tryAgain(ObservableCollection<ThreeColumnList> tcl)
        {
            //Loading Folder
            var _folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
            _folder = await _folder.GetFolderAsync("Lists");

            //Get the file
            var _file = await _folder.GetFileAsync("splist.txt");

            // read content
            IList<string> _ReadLines = await Windows.Storage.FileIO.ReadLinesAsync(_file);

            int i = 0;
            foreach (var _line in _ReadLines)
            {
                i++;
                string _first = "" + _line.Split('-')[0];
                string _second = "" + _line.Split('-')[1];
                string _third = "" + _line.Split('-')[2];
                tcl.Add(new ThreeColumnList { Name = _first, Age = _second, Job = _third });
            }
            Debug.WriteLine("Count is " + i);
        }
    }
}

MainPage.xaml

<Page
x:Class="TestUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Page.Resources>
    <!-- x:DataType="<Name Of Class>" -->
    <DataTemplate x:Key="ThreeColumnListDataTemplate" x:DataType="local:ThreeColumnList">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
            <TextBlock Grid.Column="0" Text="{x:Bind Name}" HorizontalAlignment="Left" FontSize="16" Margin="20,20,20,20" />
            <TextBlock Grid.Column="1" Text="{x:Bind Age}" HorizontalAlignment="Left" FontSize="16" Margin="20,20,20,20" />
            <TextBlock Grid.Column="2" Text="{x:Bind Job}" HorizontalAlignment="Right" FontSize="16" Margin="20,20,20,20" />
        </StackPanel>
    </DataTemplate>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="100" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />

    </Grid.ColumnDefinitions>
    <TextBlock Grid.Row="1" 
               Name="ResultTextBlock" 
               FontSize="24" 
               Foreground="Red" 
               FontWeight="Bold" 
               Margin="20,20,0,0" />
    <!--  ItemsSource="x:Bind <Variable from the CS(Code) Class>   -->
    <ListView Grid.ColumnSpan="3" ItemsSource="{x:Bind ThreeColumnLists}" 
              ItemTemplate="{StaticResource ThreeColumnListDataTemplate}">
    </ListView>

</Grid>

Output:

You have to await or Wait() on Task.

Change signature from
public static async void readList(List<ThreeColumnList> tcl)
to
public static async Task readList(List<ThreeColumnList> tcl)
And invoke it like readList(threecolumnlists).Wait();

This breaks asynchrony of your code, but will work. The best way would be to change GetList() to be async and run this in Task showing spinner or progress bar to user:

public SPList()
{
    this.InitializeComponent();
    Task.Run(async () =>
    {
        IsLoading = true;
        ThreeColumnLists = await ThreeColumnListManager.GetList();
        IsLoading = false;
    }
}

private bool _isLoading;
public bool IsLoading
{
    get { return _isLoading; }
    set
    {
        if(_isLoading != value)
        {
            _isLoading = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLoading));
        }
    }
}

Going out on a limb here but:

The async operation means it can be run on a different thread so it's possible that the end result of reading the file (a list of ThreeColumnList) is living on a different thread. Do you receive (or have you suppressed) exceptions that occur during or shortly after loading a file? You might consider double-checking that you are marshalling the list to the UI thread before binding occurs if it's owner thread is not the UI thread to avoid this issue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!