【问题标题】:Xamarin.Forms Directory PickerXamarin.Forms 目录选择器
【发布时间】:2019-12-15 21:55:21
【问题描述】:

我想将文件保存在用户选择的文件夹中,这就是为什么我想向用户提供目录列表,用户将能够选择他想要导出数据的目录。不幸的是,我找不到目录/文件夹选择器的任何示例,我只是找到了一个对我没用的文件选择器..

https://github.com/jfversluis/FilePicker-Plugin-for-Xamarin-and-Windows

是否有任何组件可以为 Xamarin.Forms 选择文件夹?实际上我只是在为 Android 做,但我们使用 Xamarin.forms

【问题讨论】:

    标签: xamarin.forms directory picker


    【解决方案1】:

    我想不出。 使用 netstandard,一切都变得更加简单,因为您可以使用经典的 c# File api 来获取文件夹。

    您只需要知道特殊文件夹和 android 文件夹之间的映射(例如):

    System.Environment.SpecialFolder    Path
    ApplicationData                     INTERNAL_STORAGE/.config
    Desktop                             INTERNAL_STORAGE/Desktop
    LocalApplicationData                INTERNAL_STORAGE/.local/share
    MyDocuments                         INTERNAL_STORAGE
    MyMusic                             INTERNAL_STORAGE/Music
    MyPictures                          INTERNAL_STORAGE/Pictures
    MyVideos                            INTERNAL_STORAGE/Videos
    Personal                            INTERNAL_STORAGE
    

    来源:https://docs.microsoft.com/en-US/xamarin/android/platform/files/

    同样适用于 ios:

    https://docs.microsoft.com/en-US/xamarin/ios/app-fundamentals/file-system

    但是实现起来真的很简单,只需要枚举所有文件夹,并在ListView中显示即可。

    编辑:有关实施的更多细节。

    其实你想编写一个“目录浏览器”,很简单,概念就在这里。

    • 您的Page 中有一个ListView
    • 您的Page 中有一个Cancel 按钮和一个Select 按钮
    • 您的ViewModel 中有一个CurrentPath
    • 您将CurrentPath 绑定到主页的Title
    • 您的ViewModel 中有一个List<DirectoryViewModel> Directories

    每次用户点击列表中的一项时:

    • 您在当前路径中添加目录名称
    • 您从新路径中获取所有目录,并更新您的 Directories 属性(不要忘记RaisePropertyChange(nameof(Directories))
    • ListView 将相应更新

    每次你回来:

    • 您删除了当前路径的最后一部分
    • 和以前一样

    如果你到达根路径“/”,点击返回时什么都不做。

    哦,你可以使用这个Grid 组件来代替ListView,会更好;)

    https://github.com/roubachof/Sharpnado.Presentation.Forms#grid-Layout

    【讨论】:

    • 感谢您的回复,但我需要一个 gui 吗?我必须创建自己的 gui 吗?
    • 是的,你有,但它首先出现更简单(请参阅我编辑的答案)
    【解决方案2】:

    您可以对其进行编辑以使其工作..

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Java.IO;
    using Java.Util;
    
    namespace Android.Basic.IO
    {
        
        public class DirectoryPicker : ListActivity
        {
    
    
            public const String START_DIR = "startDir";
            public const String ONLY_DIRS = "onlyDirs";
            public const String SHOW_HIDDEN = "showHidden";
            public const String CHOSEN_DIRECTORY = "chosenDir";
            public const int PICK_DIRECTORY = 43522;
            private File dir;
            private Boolean showHidden = false;
            private bool onlyDirs = true;
            public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
            {
                base.OnCreate(savedInstanceState, persistentState);
                Bundle extras = Intent.Extras;
                dir = OS.Environment.ExternalStorageDirectory;
                if (extras != null)
                {
                    String preferredStartDir = extras.GetString(START_DIR);
                    showHidden = extras.GetBoolean(SHOW_HIDDEN, false);
                    onlyDirs = extras.GetBoolean(ONLY_DIRS, true);
                    if (preferredStartDir != null)
                    {
                        File startDir = new File(preferredStartDir);
                        if (startDir.IsDirectory)
                        {
                            dir = startDir;
                        }
                    }
                }
    
                SetContentView(Resource.Layout.folder_chooser_activity);
                var title = dir.AbsolutePath.ToString();
                Title = (title);
                Button btnChoose = (Button)FindViewById(Resource.Id.btnChoose);
                String name = dir.Name;
                if (name.Length == 0)
                    name = "/";
                btnChoose.Text = ("Choose " + "'" + name + "'");
                btnChoose.Click += delegate
                  {
                      returnDir(dir.AbsolutePath);
                  };
                ListView lv = this.ListView;
                lv.TextFilterEnabled = (true);
    
                if (!dir.CanRead())
                {
                    Context context = ApplicationContext;
                    String msg = "Could not read folder contents.";
                    Toast.MakeText(context, msg, ToastLength.Long).Show();
                    return;
                }
                var files = filter(dir.ListFiles(), onlyDirs, showHidden);
                String[] names = Names(files);
                ListAdapter = (new ArrayAdapter<String>(this, Resource.Layout.folder_chooser_item, names));
                lv.ItemClick += (ff, gg) =>
                {
                    var position = gg.Position;
                    if (!files[gg.Position].IsDirectory)
                        return;
                    String path = files[position].AbsolutePath;
                    var intent = new Intent(this, typeof(DirectoryPicker));
                    intent.PutExtra(DirectoryPicker.START_DIR, path);
                    intent.PutExtra(DirectoryPicker.SHOW_HIDDEN, showHidden);
                    intent.PutExtra(DirectoryPicker.ONLY_DIRS, onlyDirs);
                    StartActivityForResult(intent, PICK_DIRECTORY);
                };
    
            }
    
            protected void OnActivityResult(int requestCode, int resultCode, Intent data)
            {
                if (requestCode == PICK_DIRECTORY && resultCode == (int)Result.Ok)
                {
                    Bundle extras = data.Extras;
                    String path = (String)extras.Get(DirectoryPicker.CHOSEN_DIRECTORY);
                    returnDir(path);
                }
            }
    
            private void returnDir(String path)
            {
                Intent result = new Intent();
                result.PutExtra(CHOSEN_DIRECTORY, path);
                SetResult(Result.Ok, result);
                Finish();
            }
    
    
            public List<File> filter(File[] file_list, bool onlyDirs, bool showHidden)
            {
                var files = new List<File>();
                foreach (var file in file_list)
                {
                    if (onlyDirs && !file.IsDirectory)
                        continue;
                    if (!showHidden && file.IsHidden)
                        continue;
                    files.Add(file);
                }
                Collections.Sort(files);
                return files;
            }
    
            public String[] Names(List<File> files)
            {
                String[] names = new String[files.Count];
                int i = 0;
                foreach (var file in files)
                {
                    names[i] = file.Name;
                    i++;
                }
                return names;
            }
        }
    }
    

    启动活动作为结果,然后在 OnActivityResult 中捕获

    if (requestCode == DirectoryPicker.PICK_DIRECTORY && resultCode == Result.Ok)
                {
                    Bundle extras = data.Extras;
                    String path = (String)extras.Get(DirectoryPicker.CHOSEN_DIRECTORY);
                    // do stuff with path
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-26
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      相关资源
      最近更新 更多