FileDialog使用Avalonia上的OpenFileDialog循环打开

时间:2019-06-14 19:59:58

标签: openfiledialog avaloniaui

我正在Avalonia中创建一个简单的概念证明UI。单击按钮访问所选文件的内容并在文本框中显示文件的路径时,我需要使用OpenFileDialog。

我创建了异步Task方法,以打开文件对话框并将所选文件另存为字符串,然后将任务传递给按钮事件处理程序。运行该应用程序并单击该按钮时,将打开文件对话框,但是当打开文件或关闭文件对话框窗口时,将重新打开文件对话框而不更新文本框。

相关控件:

<TextBox Text="{Binding Path}" Margin="0 0 5 0" Grid.Column="0" IsReadOnly="True" />
<Button Content="Browse" Click="Browse_Clicked" Margin="0 0 0 0" Grid.Column="1" />

隐藏代码:

public class MainWindow : Window
{
   public MainWindow()
   {
      InitializeComponent();
      this.DataContext = new TxtViewModel() { Path = @"C:\..." };
#if DEBUG
      this.AttachDevTools();
#endif
   }

   private void InitializeComponent()
   {
      AvaloniaXamlLoader.Load(this);
   }

   public async Task<string> GetPath()
   {
      OpenFileDialog dialog = new OpenFileDialog();
      dialog.Filters.Add(new FileDialogFilter() { Name = "Text", Extensions =  { "txt" } });

      string[] result = await dialog.ShowAsync(this);

      if (result != null)
      {
         await GetPath();
      }

      return string.Join(" ", result);
   }

   public async void Browse_Clicked(object sender, RoutedEventArgs args)
   {
      string _path = await GetPath();

      var context = this.DataContext as TxtViewModel;
      context.Path = _path;
   }
}

查看模型:

class TxtViewModel : INotifyPropertyChanged
{
   private string _path;

   public string Path
   {
      get => _path;
      set
      {
         if (value != _path)
         {
            _path = value;
            OnPropertyChanged();
         }
      }
   }

   public event PropertyChangedEventHandler PropertyChanged;

   protected virtual void OnPropertyChanged([CallerMemberName] string 
   propertyName = null)
   {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
}

我要完成的工作是单击“浏览”按钮时,调用GetPath()Task方法并打开文件对话框,允许用户选择文本文件。选择文件后,文件对话框关闭,文本框绑定更新以显示所选文件的路径。稍后,我希望它可以将文本文件的内容保存到字符串中,但是我希望它首先起作用。

实际上发生的是单击“浏览”按钮时,打开文件对话框,但是当选择文件或关闭/取消文件对话框时,它会重新打开,而不会更新绑定文本框的路径。

我对Avalonia和WPF都是陌生的,因此我愿意采用更好的方法来实现这一目标。

1 个答案:

答案 0 :(得分:0)

Array is [1, 1, 2, 3, 1, 2, 1]

Query 1: l=0, r=6, Output: 4, 2, 3 (4 for 4 1's, 2, for 2 2's and 1 for 1 3)
Query 2: l=3, r=5, Output: 1, 1, 1

打开对话框后,您将递归调用函数,导致无限期地调用const ll N = 1e6+5; ll arr[N]; unordered_map< ll, ll > tree[4 * N]; int n, q; void build (ll node = 1, ll start = 1, ll end = n) { if (start == end) { tree[node][arr[start]] = 1; return; } ll mid = (start + end) / 2; build (2 * node, start, mid); build (2 * node + 1, mid + 1, end); for (auto& p : tree[2 * node]) { ll x = p.ff; ll y = p.ss; tree[node][x] += y; } for (auto& p : tree[2 * node + 1]) { ll x = p.ff; ll y = p.ss; tree[node][x] += y; } } vector< ll > query (ll node, ll l, ll r, ll start = 1, ll end = n) { vector< ll > ans; if (end < l or start > r) return ans; if (start >= l and end <= r) { for (auto p : tree[node]) { ans.push_back (p.ss); } return ans; } ll mid = (start + end) / 2; vector< ll > b = query (2 * node, l, r, start, mid); ans.insert (ans.end (), b.begin (), b.end ()); b = query (2 * node + 1, l, r, mid + 1, end); ans.insert (ans.end (), b.begin (), b.end ()); return ans; }