Closed DanBiscotti closed 3 years ago
Hey! Thanks a lot for a detailed description of the problem with a complete code example! That helped quite a lot with the investigation.
It was indeed a genuine bug. Whenever one swaps the ConsoleManager.Content
, the framework clears the window completely and draws the full content of that new control on the screen. The problem was that the ConsoleManager
was not clearing its internal buffer during that operation. When redrawing the content, it wasn't actually drawing the border, as according to the internal buffer that border didn't change (even though the actual terminal has been full cleared).
The bug was fixed in the newly released version 1.4.1. The fix is simple - the ConsoleManager
now clears the buffer when the ConsoleManager.Content
is swapped. Later on I will also try to optimize it so that if the console was already initialized, the terminal will not be fully cleared on those swaps (as there is no need for that).
So now (after upgrading the package), your code should work.
I also took a liberty of analyzing your code (even though I know it's just a quick snippet to test things out). Two comments:
TestListener
in the OnInput
as you already have a while(!flag.Exit)
in your main method that can reuse the existing instance (and in result you will not grow the call stack on each key stroke)ConsoleManager
, you can just change the Text
of your nested TextBlock
. This way only that text will be re-rendered and your program will be faster.Suggested fix:
public class TestFlag
{
public bool Exit { get; set; }
}
public class TestListener : IInputListener
{
private readonly TestFlag flag;
private readonly TestView testView;
private int i = 1;
public TestListener(TestFlag flag, TestView testView)
{
this.flag = flag;
this.testView = testView;
}
public void OnInput(InputEvent inputEvent)
{
if (inputEvent.Key.Key == System.ConsoleKey.Enter)
{
testView.Value = ++i;
inputEvent.Handled = true;
}
else if (inputEvent.Key.Key == System.ConsoleKey.Q)
{
flag.Exit = true;
inputEvent.Handled = true;
}
}
}
public class TestView : SimpleControl
{
private readonly TextBlock textBlock = new TextBlock();
public TestView()
{
Content = new Border { Content = textBlock };
Value = 1;
}
public int Value
{
set => textBlock.Text = $"test {value}";
}
}
class Program
{
static void Main()
{
var testView = new TestView();
ConsoleManager.Setup();
ConsoleManager.Content = testView;
var flag = new TestFlag();
var listener = new TestListener(flag, testView);
while (!flag.Exit)
{
Thread.Sleep(10);
ConsoleManager.ReadInput(new[] { listener });
}
}
}
Please let me know if your problem is indeed fixed.
Hey, yes thanks that fixed it 👍 and thanks for the pointers, I will remember to try and avoid redrawing the whole screen
Hi, thanks for a great library. I was testing something out for a project in which I want to update the
ConsoleManager.Content
from within theIInputListener
so I created a few test files and it seems that the window isn't updating properly. I wondered whether perhaps it was because you shouldn't be able to do this, or if it is a genuine bug (or maybe something I'm missing)?Code
Program.cs
TestFlag.cs
TestListener.cs
TestView.cs
Result
The first iteration appears as you would expect:
However subsequent iterations look like only the changed cell is displayed (no border or "test"):