spectre.console
spectre.console copied to clipboard
Added property changing handling into listprompt
No idea if its the best way to do it but it works
@JKamsker Thanks for your PR.
Do you have a demo showing how this works in practice? Not sure that this approach will work well since we want to be in control of when we redraw the list. I suspect that this approach might introduce rendering bugs in some scenarios.
@patriksvensson Uh nice, thanks for the fast reply! Kinda urgent (for me), cause i need it for work xD
Basically i have sort of a "sqlconnectionstring scanner" which evaluates connectionstrings on the fly and the user should be able to choose which one he would like, even if the scanner hasnt finished yet
Here is my demo:
using Spectre.Console;
using System.Collections;
using System.ComponentModel;
namespace SpectreTester;
internal class Program
{
private static void Main(string[] args)
{
var choices = new SmartSelections
{
{"Get the version of the database ", (_) =>
{
AnsiConsole.MarkupLine("A");
}
},
{"List all migrations", (_) => { AnsiConsole.MarkupLine("B"); } },
{"List all pending migrations", (_) => { AnsiConsole.MarkupLine("C"); } },
{"Update the database to the latest version", (_) => { AnsiConsole.MarkupLine("D"); } },
{"Update the database to a specific version", (_) => { AnsiConsole.MarkupLine("E"); } },
};
_ = Task.Run(async () =>
{
await Task.Delay(1000);
choices.First().Selection = "Hi mom";
});
var prompt = new SelectionPrompt<SmartSelectionItem>()
.Title("What would you like to do?")
.PageSize(10)
.MoreChoicesText("[grey](Move up and down to reveal more options)[/]")
.AddChoices(choices);
var selection = AnsiConsole.Prompt(prompt);
}
}
internal class SmartSelections : IEnumerable<SmartSelectionItem>
{
private readonly List<SmartSelectionItem> _items = new();
public void Add(string selection, Action<SmartSelectionItem> onSelect)
{
_items.Add(new SmartSelectionItem(selection, onSelect));
}
public IEnumerator<SmartSelectionItem> GetEnumerator()
{
return _items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal class SmartSelectionItem : INotifyPropertyChanged
{
private string selection;
private readonly Func<SmartSelectionItem, int> _onSelect;
public string Selection
{
get => selection;
set
{
selection = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Selection)));
}
}
public event PropertyChangedEventHandler? PropertyChanged;
public SmartSelectionItem(string selection, Action<SmartSelectionItem> onSelect)
{
Selection = selection;
_onSelect = (x) => { onSelect(x); return 0; };
}
public SmartSelectionItem(string selection, Func<SmartSelectionItem, int> onSelect)
{
Selection = selection;
_onSelect = onSelect;
}
public override string ToString() => Selection;
public void OnSelect() => _onSelect(this);
}