你如何在每个文件名的c#windows phone中动态创建按钮?

时间:2015-04-09 23:45:39

标签: c# button foreach windows-phone

我的应用程序在SD卡上创建了一个名为" RpgApp" 什么时候它创建一个字符,它将该字符保存为该文件夹中的html文件(所有这些工作,我在清单中有SD卡访问,我有.html添加到文件关联)。这是重要的信息,因为没有sdcard访问或文件关联我将获得未经授权的访问异常。

我现在想在堆栈面板中为每个文件创建一个按钮,这是使用

的代码
private async Task readFiles()
    {
        z.test.Clear();
        StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
        StorageFolder folder = (await externalDevices.GetFolderAsync("RpgApp"));
        IReadOnlyList<StorageFile> fileList = await folder.GetFilesAsync();
        foreach (StorageFile file in fileList)
        {
            z.test.Add(file.Name);
        }
    }


    public async void buttonTest()
    {
        await readFiles();
        foreach (string name in z.test)
        {
            Button button1 = new Button();
            button1.Height = 75;
            button1.Content = name;
            button1.Name = name;
            testStackPanal.Children.Add(button1);
        }
    }

就ide而言,没有错误。但是当我尝试运行buttonTest()时,我得到两个Systen.UnauthorizedAccessExceptions这是我在创建文件之前得到的错误(通过将.html添加到文件关联来修复) RpgApp文件夹中没有其他文件,只有forename-surname.html

我一直在这个大部分时间都在工作,并且我坚持认为任何想法

windows phone通用应用程序(Windows Phone 8.1及以上版本)

EDIT 注释掉等待readFiles();并向z.test添加字符串然后完全工作,因此它链接到文件的读取,但我们知道应用程序可以访问该文件夹和html文件,因为它可以创建文件夹和文件。

EDIT2 抛出检查每一行,就是导致错误的这一行

StorageFolder folder = (await externalDevices.GetFolderAsync("RpgApp"));
在readFiles方法中

,但这正是文件夹名称

1 个答案:

答案 0 :(得分:0)

在您的方法中,您正在调用在后台线程上执行的异步任务。当您尝试从后台线程访问在UI线程上创建的对象时,抛出异常Systen.UnauthorizedAccessExceptions异常。

我会修改您的代码,以便在您完成读取文件后,在UI线程上完成所有后续操作。如(注意未经测试)。

public async void buttonTest()
{
    await readFiles();
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        foreach (string name in z.test)
        {
            Button button1 = new Button();
            button1.Height = 75;
            button1.Content = name;
            button1.Name = name;
            testStackPanal.Children.Add(button1);
        }
    });
}

方法Deployment.Current.Dispatcher.BeginInvoke() { ... });旨在执行操作UI的方法。 UI只能通过UI线程进行操作。

上面的代码适用于Windows Phone 8,但是8.1已经替换了一些方法并从WP8中访问Dispatcher。

public async void buttonTest()
{
    await readFiles();
    CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        foreach (string name in z.test)
        {
            Button button1 = new Button();
            button1.Height = 75;
            button1.Content = name;
            button1.Name = name;
            testStackPanal.Children.Add(button1);
        }
    });
}

修改

好的..所以我已经创建了自己的测试环境来解决这个问题,而且我没有走上正轨。原来问题是正确读取SD卡文件。这是通过这些步骤在模拟器上完成的。

1)打开包清单并转到Declarations标签。从这里我创建了一个新的FileType Association(如下图所示) enter image description here

2)转到Capabilities标签,确保您已选择Removable Storage(因此我们可以阅读存储空间)。

现在,下一部分仅在我改变了从设备读取文件的方式时才起作用。我没有尝试加载一个文件夹而是遍历所有文件夹,而是在尝试查询特定文件夹时遇到了相同的“拒绝访问”错误(不确定原因)。我修改了读取文件的代码,以迭代遍历所有文件夹和文件,并根据需要添加文件。

async Task readAllFiles(StorageFolder folder)
{
    var files =await folder.GetFilesAsync();
    foreach (var file in files)
    {
        test.Add(file.Name);
    }

    var folders = await folder.GetFoldersAsync();
    foreach (var child in folders)
        await readAllFiles(child);
}


public async void buttonTest()
{
    test.Clear();
    StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
    var folders = await externalDevices.GetFoldersAsync();
    foreach (var folder in folders)
    {
        await readAllFiles(folder);
    }
    CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        foreach (string name in test)
        {
            Button button1 = new Button();
            button1.Height = 75;
            button1.Content = name;
            button1.Name = name;

            testStackPanal.Children.Add(button1);
        }
    });
}

您会注意到readAllFiles方法是递归调用自己从父文件夹。我还为文件名创建了一个简单的List<string> test。这似乎有效。

现在,如果您真的只想阅读RpgApp文件夹,可以按如下方式修改代码。现在请注意,如果Folder为Null或文件夹名称为RpgApp,则返回false。如果您确定RpgApp文件夹将始终位于可移动存储的根目录中,我们可以更改这一点。

async Task<bool> continueToReadAllFiles(StorageFolder folder)
{
    if (folder == null)
        return false;
    if (folder.Name.Equals("RpgApp", StringComparison.CurrentCultureIgnoreCase))
    {
        var files = await folder.GetFilesAsync();
        foreach (var file in files)
        {
            test.Add(file.Name);
        }
        return false;
    }
    var folders = await folder.GetFoldersAsync();
    foreach (var child in folders)
        if (!await continueToReadAllFiles(child))
            return false;

    return true;
}


public async void buttonTest()
{
    test.Clear();
    StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
    var folders = await externalDevices.GetFoldersAsync();
    foreach (var folder in folders)
    {
        if (!await continueToReadAllFiles(folder))
            break;
    }
    //.... commented out
}