首页 文章

UWP FolderPicker窗口打开但已冻结

提问于
浏览
1

基本的想法是我有一个UWP应用程序从本地保存的json文件中提取用户数据,并且在不同时间它可以从文件中提取完整的对象列表,但它总是检查用户是否已设置数据的位置,如果没有,则通过FolderPicker提示用户设置位置 . 在这种情况下,我有一个组合框,可以在选择标准和输入文本后帮助过滤对象 . 这是调用堆栈:

UWPMiniatures.exe!UWPMiniatures.Data.MiniDAL.SetSaveFolder()第98行C#符号已加载 . UWPMiniatures.exe!UWPMiniatures.Data.MiniDAL.LoadAllAsync()第71行C#已加载符号 . UWPMiniatures.exe!UWPMiniatures.Data.MiniDataService.Load()第36行C#已加载符号 . UWPMiniatures.exe!UWPMiniatures.MainPage.FilterGridView(字符串提交)行156 C#符号已加载 . UWPMiniatures.exe!UWPMiniatures.MainPage.SearchIcon_Click(object sender,Windows.UI.Xaml.RoutedEventArgs e)第95行C#符号已加载 .

因此,使用后备词,在这里调用FolderPicker:

private async Task SetSaveFolder()
{
    if(!StorageApplicationPermissions.FutureAccessList.ContainsItem("PickedFolderToken"))
    {
        FolderPicker folderPicker = new FolderPicker();
        folderPicker.SuggestedStartLocation = PickerLocationId.Desktop;
        folderPicker.FileTypeFilter.Add("*");
        folderPicker.CommitButtonText = "Pick A Folder To Save Your Data";
        StorageFolder folder = await folderPicker.PickSingleFolderAsync();
        if (folder != null)
        {
            // Application now has read/write access to all contents in the picked folder (including other sub-folder contents)
            StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
            var userFolder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync("PickedFolderToken");
            var file = await userFolder.CreateFileAsync("AllMinisList.json",CreationCollisionOption.OpenIfExists);
            var imagefolder = await userFolder.CreateFolderAsync("Images");
        }

    }
}

文件夹选择器对话框打开,文件夹旁边有一个闪烁的光标:但是当我点击任何地方时没有任何反应,我也无法输入文件夹:文本框 . 现在,将这个相同的代码放在一个新项目中,并在响应单击事件时调用它可以正常工作:Dialog打开,我创建一个新文件夹或选择一个现有文件夹,它将被添加到将来的访问列表中 . 不知道如何解决这个问题,但问题似乎在于调用FolderPicker的实际代码 . 这是另一个调用函数的代码

private void SearchIcon_Click(object sender, RoutedEventArgs e)
{
    FilterGridView(SearchTextBox.Text);
    SearchTextBox.Text = "";
}

    private async void FilterGridView(string submission)
{
    var selected = FilterComboBox.SelectedValue;

    miniDS = new MiniDataService();  

   if(selected.ToString()=="All")
    {
        MiniList.Clear();
        List<Miniature> fullList = await miniDS.Load();
        fullList.ForEach(m => MiniList.Add(m));
    }
    else if (selected.ToString() == "Quantity")
    {
        List<Miniature> fullList = await miniDS.Load();
        var templist = fullList.AsQueryable()
         .Where($"{selected} = @0", submission); ;
        MiniList.Clear();
        templist.ToList<Miniature>()
            .ForEach(m => MiniList.Add(m));
    }
    else
    {
        List<Miniature> fullList = await miniDS.Load();
        var templist = fullList.AsQueryable()
        .Where($"{selected}.StartsWith(@0)", submission);
        MiniList.Clear();
        templist.ToList<Miniature>()
            .ForEach(m => MiniList.Add(m));
    }
}

除了传递呼叫之外,MiniDataService和MiniDal在这方面做得不多 . 我有什么想法可以解决这个问题?更新:一些额外的信息,我将SetSaveFolder()中的代码直接复制到按钮的新事件处理程序中,单击它,我得到FolderPicker,功能完美 . 但这根本不是所需的功能 . 我需要直接或间接从我的数据服务中调用它 . 所以这就是它创建的地方:

public sealed partial class MainPage : Page
    {
        /// <summary>
        /// MiniList is the list of minis currently being displayed
        /// </summary>
        private ObservableCollection<Miniature> MiniList;
        private MiniDataService miniDS;       
        private List<string> FilterComboList;
        private Miniature NewMini;

        public MainPage()
        {
            this.InitializeComponent();           
            miniDS = new MiniDataService();
            MiniList = new ObservableCollection<Miniature>();         
            FilterComboList = PopulateFilterCombo();
            NewMini = new Miniature();
            MyFrame.Navigate(typeof(MiniListPage), MiniList);
        }
...

所以问题似乎与从这个“静态”对象调用FolderPicker的事实有关 . 这是一个线程问题吗?我认为在UWP中我总是在UI线程上,因为在顶级事件处理程序调用folderPicker我无法理解为什么UI似乎被锁定 .

1 回答

  • 1

    所以我想我已经明白了,虽然我不知道为什么会这样 . 如果有人能告诉我,我会欣赏它 . 所以从调用 List<Miniature> fullList = await miniDS.Load(); 这是方法:

    public async Task<List<Miniature>> Load()
            {
                return await minidal.LoadAllAsync();
            }
    
    public async Task<List<Miniature>> LoadAllAsync()
            {
    
                List<Miniature> MiniCollection = new List<Miniature>();
                if (StorageApplicationPermissions.FutureAccessList.ContainsItem("PickedFolderToken"))
                {
                    try
                    {
                        var userFolder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync("PickedFolderToken");
                        var file = await userFolder.GetFileAsync("AllMinisList.json");
                        var data = await file.OpenReadAsync();
    
                        using (StreamReader stream = new StreamReader(data.AsStream()))
                        {
                            string text = stream.ReadToEnd();
                            MiniCollection = JsonConvert.DeserializeObject<List<Miniature>>(text);
                        }
                    }
                    catch(Exception e)
                    {
                        throw e;
                    }
                }
                else
                {
                    SetSaveFolder().Wait();
                    return MiniCollection;
                }
    
                return MiniCollection;
            }
    

    所以问题就在这里:

    SetSaveFolder().Wait();
    

    当我用它替换它

    await SetSaveFolder();
    

    它工作正常 . 我可以点击folderPicker,它可以完成预期的工作 . 我想我虽然.Wait()是在你没有返回任何东西时使用的,但它似乎还有更多的东西!

相关问题