2016-12-30 12 views
0

私は現在、関数の1つがcsvファイルからデータを取得し、そのデータを使用してリストビューにデータを格納する、墓地の訪問者用キオスク用のアプリケーションを開発しています。次のコードは、データを受け取り、リスト型の墓に戻すコードです。ApplicationData.Current.LocalFolderからKnownfolders.DocumentsLibraryに切り替える

public class Grave 
    { 
     public string plots { get; set; } 
     public string DOBS { get; set; } 
     public string lastNames { get; set; } 
     public string firstNames { get; set; } 
     public string companys { get; set; } 
     public string regts { get; set; } 
     public string unitTypes { get; set; } 
     public string states { get; set; } 
     public string ranks { get; set; } 
     public string sections { get; set; } 
     public string image { get; set; } 
     public string text { get; set; } 
     public string notenums { get; set; } 
    } 



public class GraveManager 
{ 



    public static List<Grave> GetGrave() 
    { //points to desired folder 
     StorageFolder folder = ApplicationData.Current.LocalFolder; 

     string csvPath = folder.Path + @"\PGexcel.csv"; 
     //loads .csv file from folder 
     Csv csv = new Csv(); 

     //property that tells csv parser to not treat the first row as data 
     csv.HasColumnNames = true; 

     bool success1; 
     success1 = csv.LoadFile(csvPath); 

     //name of columns 
     string plot = "Plot", DOB = "Date_of_Death", lastName = "Last_Name", firstName = "First_Name", company = "Company", regt = "Regt", state = "State", unitType = "Unit_Type", Rank = "Rank", Section = "Section", Notables= "Notables"; 


     //initialize string of arrays for each column 
     string[] OCplots = new string[csv.NumRows]; 
     string[] OCDOBS = new string[csv.NumRows]; 
     string[] OClastNames = new string[csv.NumRows]; 
     string[] OCfirstNames = new string[csv.NumRows]; 
     string[] OCcompanys = new string[csv.NumRows]; 
     string[] OCregts = new string[csv.NumRows]; 
     string[] OCunitTypes = new string[csv.NumRows]; 
     string[] OCstates = new string[csv.NumRows]; 
     string[] OCranks = new string[csv.NumRows]; 
     string[] OCsections = new string[csv.NumRows]; 
     string[] OCimage = new string[csv.NumRows]; 
     string[] OCtext = new string[csv.NumRows]; 
     string[] OCnotenums = new string[csv.NumRows]; 


     //populates the arrays with values from .csv file 
     for (int i = 0; i < csv.NumRows; i++) 
     { 

      OCplots[i] = csv.GetCellByName(i, plot); 
      OCDOBS[i] = csv.GetCellByName(i, DOB); 
      OClastNames[i] = csv.GetCellByName(i, lastName); 
      OCfirstNames[i] = csv.GetCellByName(i, firstName); 
      OCcompanys[i] = csv.GetCellByName(i, company); 
      OCregts[i] = csv.GetCellByName(i, regt); 
      OCunitTypes[i] = csv.GetCellByName(i, unitType); 
      OCranks[i] = csv.GetCellByName(i, Rank); 
      OCsections[i] = csv.GetCellByName(i, Section); 
      OCstates[i] = csv.GetCellByName(i, state); 
      OCnotenums[i] = csv.GetCellByName(i, Notables); 
     } 



     //concantenate arrays with .jpg .txt to call for corresponding files 
     for (int i = 0; i < csv.NumRows; i++) 
     { 
      //OCimage[i] = "C:/Users/POGR_ADMIN/AppData/Local/Packages/6b3614f6-6a5f-48fc-9687-80291e70b64d_phwtyg9y34v1t/LocalState/" + OCplots[i] + ".jpg"; 
      OCimage[i] = folder.Path + @"\" + OCplots[i] + ".jpg"; 
      OCtext[i] = folder.Path + @"\"+ OCplots[i] + ".txt"; 
     } 

     var graves = new List<Grave>(); 



     //attempt to populate List using the for loop 
     for (int i = 0; i < csv.NumRows; i++) 
     { 
      graves.Add(new Grave { plots= OCplots[i], DOBS = OCDOBS[i], lastNames = OClastNames[i], firstNames = OCfirstNames[i], companys = OCcompanys[i], regts = OCregts[i], states = OCstates[i], unitTypes = OCunitTypes[i],ranks = OCranks[i], sections = OCsections[i], image = OCimage[i], text = OCtext[i], notenums = OCnotenums[i] }); 

     } 




     return graves;    

    } 
} 

私はその後、別のページにリスト型の墓を初期化し、コンストラクタが呼び出されたときにメソッドを呼び出すことによって、それを埋めます。

public List<Grave> Graves; 

    public FindaGrave() 
    { 
     this.InitializeComponent(); 
     GraveInitializer(); 

    } 

    public void GraveInitializer() 
    { 
     Graves = GraveManager.GetGrave(); 
    } 

このコードは完全にうまく動作し、私が想像していたとおりにリストビューを作成します。しかし、私が気づいたのは、csvファイルに多数のエラーがあり、ヒューマンエラーのために見つけることを計画していることです。それが言われて、彼らはcsvファイルを変更することができるようにしたいと思うし、彼らは(私の助けなしに)アプリケーションをリロードした後に変更が表示されます。ため、私はそうするフィットを見た唯一の方法はStorageFolder folder = KnownFolders.DocumentsLibrary;

StorageFolder folder = ApplicationData.Current.LocalFolder;を変更することであろうパッケージ化されたローカル状態フォルダに私は、ファイルがドキュメントライブラリにあったことを確認した場合、アプリに機能を追加したことを感じましたパッケージのマニフェストは<uap:Capability Name="documentsLibrary" />のようになり、同じように動作するはずの適切なファイルタイプの関連付けを追加します。しかし、私が実行するとリストは表示されなくなり、ちょっとデバッグしたあともfolder.Pathの値はなくなり、string csvPathは `\ PGexcel.csv"に等しくなります。私は完全な敗北に直面しています。なぜなら、迅速な修正が必要であると思ったことは、非常に困難なものになってしまいました。さらに、私はUWPの初心者です。私は何日も探していて解決策を見つけることができず、この問題についての援助は非常に高く評価されます。あなたは人生の節約になるでしょう!

+0

私たちはあなたの問題でダイビングする前に。あなたは、ドキュメントライブラリの機能が制限されていることを知っていますか?ソース:https://msdn.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations –

+0

私はそれを使用しない方が良いと理解していますが、このアプリケーションはサイドロードされ、本当に問題ではありませんので、店を通過してください。@DaveSmits –

答えて

0

あなたのコードを確認しましたが、問題はUWPアプリケーションがサンドボックス化されており、ApplicationDataへの完全なアクセスしか持たないことです。アプリケーションデータの外にフルパスを得ることができたとしても、それを開くことはできません。 KnownFoldersクラスで開くか、StorageApplicationPermissionsクラスに保存する必要があります

Storiage Apiを使用してファイルストリームを開き、それをcsvパーサに渡すのが最も良い方法ですが、あなたのcsvパーサーがストリームを受け入れるかどうかはわかりません

+0

DocumentsLibraryは、既知のフォルダクラスの一部です。また、csvパーサーは文字列をパスとして受け入れます。ストレージAPIの使用例を表示できますか? @DaveSmits –

+0

また、Known Folderクラスにあるので、それを使用する方法はありませんか?もしそれが当てはまるならば、私はそれが置かれた制限にかかわらずオプションとしてそれを持っていても、特にそれがサイドロードされたアプリなら、それを持っているということはかなり馬鹿だと思う。@DaveSmits –

0

UWPアプリケーションは安全である必要があるため、パスを使用してアプリケーション以外のデータファイルシステムの場所に直接アクセスすることはできません。

でも、StorageFile APIを使用できます.CSVライブラリがfileではなくstringからの入力をサポートする場合は、十分なはずです。

public static async Task<List<Grave>> GetGraveAsync() 
{ 
    //points to desired folder 
    StorageFolder folder = ApplicationData.Current.LocalFolder; 
    //find the file 
    StorageFile csvFile = await folder.GetFileAsync("PGexcel.csv"); 


    //loads .csv file from folder 
    Csv csv = new Csv(); 

    //property that tells csv parser to not treat the first row as data 
    csv.HasColumnNames = true; 

    bool success1; 

    //load the CSV data from string 
    success1 = csv.LoadFromString(await FileIO.ReadAllText(csvFile)); 

    //... rest of your code 

    return graves;    
} 

StorageApplicationPermissions.FutureAccessList

あなたの問題への最も簡単な解決策は、ユーザーがFileOpenPickerを使用して、アプリケーションの最初の起動時にファイルを選択し、StorageApplicationPermissions.FutureAccessList APIを使用して、それを保存できるようになります。このAPIを使用すると、ユーザーが選択したファイルにアクセスできるように、アクセス権を1000項目に保存できます。アプリの複数の起動でも

+0

機能性。このコードとオリジナルの違いは何ですか?ローカルの状態フォルダにアクセスできないため、必要な場合でも、csvファイルを更新したり置き換えたりすることはできません。それは私がドキュメントフォルダに行く方法を探している唯一の理由だそれはそれが可能な唯一のフォルダだから –

+1

あなたのバージョンとこれの違いは、実際にこの方法でファイルにアクセスできるはずだということですもしドキュメントライブラリの機能を宣言したら、そこに 'DocumentLibrary'を使っています。また、代わりに、 'StorageApplicationPermission.FutureAccessList'と一緒に' FileOpenPicker'を使用して、ユーザーがソースファイルを一度(アプリケーションの最初の使用中に)選択し、アプリケーションの次の起動時に保存できるようにすることもできます。ファイルを今後のアクセスリストに保存することで、必要なときにいつでも再度アクセスすることができます。 –

+0

私の答えは 'FutureAccessList'に関する情報で更新しました –