Add FilesSelected event

Allows user to do things like confirm dialogs on selecting existing file(s)
This commit is contained in:
tznind
2023-03-19 10:07:00 +00:00
parent 9c1a80e748
commit cedc4fba81
4 changed files with 89 additions and 4 deletions

View File

@@ -234,6 +234,12 @@ namespace Terminal.Gui {
private MenuBarItem allowedTypeMenu;
private MenuItem [] allowedTypeMenuItems;
/// <summary>
/// Event fired when user attempts to confirm a selection (or multi selection).
/// Allows you to cancel the selection or undertake alternative behavior e.g.
/// open a dialog "File already exists, Overwrite? yes/no".
/// </summary>
public event EventHandler<FilesSelectedEventArgs> FilesSelected;
/// <summary>
/// Initializes a new instance of the <see cref="FileDialog"/> class.
@@ -850,9 +856,11 @@ namespace Terminal.Gui {
this.MultiSelected = toMultiAccept.Select (s => s.FileSystemInfo.FullName).ToList ().AsReadOnly ();
this.tbPath.Text = this.MultiSelected.Count == 1 ? this.MultiSelected [0] : string.Empty;
this.Canceled = false;
Application.RequestStop ();
FinishAccept ();
}
private void Accept (FileInfo f)
{
if (!this.IsCompatibleWithOpenMode (f.FullName, out var reason)) {
@@ -866,8 +874,8 @@ namespace Terminal.Gui {
if (AllowsMultipleSelection) {
this.MultiSelected = new List<string> { f.FullName }.AsReadOnly ();
}
this.Canceled = false;
Application.RequestStop ();
FinishAccept ();
}
private void Accept ()
@@ -880,6 +888,18 @@ namespace Terminal.Gui {
return;
}
FinishAccept ();
}
private void FinishAccept ()
{
var e = new FilesSelectedEventArgs (this);
this.FilesSelected?.Invoke (this, e);
if(e.Cancel) {
return;
}
this.Canceled = false;
Application.RequestStop ();

View File

@@ -0,0 +1,31 @@
using System;
namespace Terminal.Gui {
/// <summary>
/// Event args for the <see cref="FileDialog.FilesSelected"/> event
/// </summary>
public class FilesSelectedEventArgs : EventArgs
{
/// <summary>
/// Set to true if you want to prevent the selection
/// going ahead (this will leave the <see cref="FileDialog"/>
/// still showing).
/// </summary>
public bool Cancel { get; set; }
/// <summary>
/// The dialog where the choice is being made. Use <see cref="FileDialog.Path"/>
/// and/or <see cref="FileDialog.MultiSelected"/> to evaluate the users choice.
/// </summary>
public FileDialog Dialog { get; }
/// <summary>
/// Creates a new instance of the <see cref="FilesSelectedEventArgs"/>
/// </summary>
/// <param name="dialog"></param>
public FilesSelectedEventArgs (FileDialog dialog)
{
Dialog = dialog;
}
}
}

View File

@@ -118,6 +118,11 @@ namespace UICatalog.Scenarios {
fd.Style.OkButtonText = rgCaption.RadioLabels [rgCaption.SelectedItem].ToString ();
// If Save style dialog then give them an overwrite prompt
if(rgCaption.SelectedItem == 2) {
fd.FilesSelected += ConfirmOverwrite;
}
if (cbIcons.Checked ?? false) {
fd.IconGetter = GetIcon;
}
@@ -170,6 +175,16 @@ namespace UICatalog.Scenarios {
};
}
private void ConfirmOverwrite (object sender, FilesSelectedEventArgs e)
{
if (!string.IsNullOrWhiteSpace (e.Dialog.Path)) {
if(File.Exists(e.Dialog.Path)) {
int result = MessageBox.Query ("Overwrite?", "File already exists", "Yes", "No");
e.Cancel = result == 1;
}
}
}
private class CaseSensitiveSearchMatcher : FileDialog.ISearchMatcher {
private string terms;

View File

@@ -118,6 +118,25 @@ namespace Terminal.Gui.Core {
Assert.False(dlg.Canceled);
}
[Theory, AutoInitShutdown]
[InlineData(true)]
[InlineData (false)]
public void CancelSelection (bool cancel)
{
var dlg = GetInitializedFileDialog ();
var openIn = Path.Combine (Environment.CurrentDirectory, "zz");
Directory.CreateDirectory (openIn);
dlg.Path = openIn + Path.DirectorySeparatorChar;
dlg.FilesSelected += (s, e) => e.Cancel = cancel;
//pressing enter will complete the current selection
// unless the event cancels the confirm
Send ('\n', ConsoleKey.Enter, false);
Assert.Equal(cancel,dlg.Canceled);
}
private void Send (char ch, ConsoleKey ck, bool shift = false, bool alt = false, bool control=false)
{
Application.Driver.SendKeys (ch, ck, shift, alt, control);