2016-12-30 1 views
0

현재 하나의 함수가 csv 파일에서 데이터를 가져 와서 해당 데이터를 사용하여 listview를 채우는 gravesite 용 방문 키오스크 용 앱을 개발하고 있습니다. 다음 코드는 데이터를 가져 와서 목록 유형 무덤에 반환하는 코드입니다.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

사용하지 않는 것이 더 좋지만이 응용 프로그램은 사이드로드되고 가게를 관통해서 정말 중요하지 않습니다[email protected] –

답변

0

나는 여러분의 코드를 확인하고 UWP 애플 리케이션은 일종의 sandbox이며 ApplicationData에 대한 완전한 액세스 권한 만 갖고 있다는 점이 문제입니다. 응용 프로그램 데이터 외부에서 전체 경로를 가져올지라도 열 수는 없습니다. KnownFolders 클래스를 통해 열거 나 StorageApplicationPermissions 클래스에 저장해야합니다.

가장 좋은 방법은 파일 스트림을 열고이를 CSV 파서로 전달하는 것입니다. CSV 파서가 스트림을 허용하는지 잘 모르겠습니다.

+0

DocumentsLibrary는 알려진 폴더 클래스 중 일부입니다. 그리고 csv 파서는 문자열을 경로로 받아들입니다. 스토리지 API를 사용하는 예를 보여줄 수 있습니까? @DaveSmits –

+0

또한 Known Folder 클래스에 있기 때문에 사용할 방법이 없습니까? 그 경우에는 제한이 무엇이든 관계없이 옵션으로 사용하기가 매우 어리 석다는 것을 알게되었습니다. 특히 사이드로드 된 앱인 경우에는 @DaveSmits –

0

UWP 앱은 안전해야하므로 경로를 사용하여 비 응용 프로그램 데이터 파일 시스템 위치에 직접 액세스 할 수 없습니다.

그래도 StorageFile 개의 API를 사용할 수 있으며 CSV 라이브러리가 파일 대신 문자열에서 입력을 지원하는 경우 충분해야합니다.

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'를 사용하여 사용자가 (app을 처음 사용할 때) 한 번 소스 파일을 선택하고 다음 번 앱 실행시에 저장하도록 할 수 있습니다. 나중에 액세스 목록에 파일을 저장하면 필요할 때마다 다시 액세스 할 수 있습니다. –

+0

답변을 'FutureAccessList'에 대한 정보로 업데이트했습니다. –