Giter Club home page Giter Club logo

consoleframework's Introduction

Hi there 👋

consoleframework's People

Contributors

elw00d avatar fornever avatar jinek avatar juancri avatar mirekvales avatar nathan130200 avatar therzok avatar trevordarcyevans avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

consoleframework's Issues

TabControl in example doesn't receive mouse clicks

I Loaded up the Examples project and made sure it was set to launch the TabControl sample. When it launched, the tabbed window shows up fine. Unfortunately, clicking on the tabs doesn't seem to change the selected tab.

I tried putting a breakpoint in the TabControl mouse handler, but it was never hit. I then put a breakpoint in the ParseInputEvent handler but couldn't get it to hit either.

Is there some extra magic required to get TabControl to handle clicks?

Docked panels

The examples I've seen show floating panels. Is it possible to do docked panels side-by-side? Like in the FAR manager interface?

Thanks.

Commands binded to Button do not work

During development I've noticed that commands binded to buttons are not executed. I thought that it may be something with my code, but the same thing is happening in provided sample apps. However commands are executed correctly when fired from menu.
I am using win10 x64 and it is a bit of showstopper to me.

edit: I've noticed that clicking on button with mouse sometimes does work, hitting enter on keyboard however does not

edit2: registering to button's onClick event works with mouse and with keyboard

Opacity matrix index out of range exception (probably because of short menu item names)

windows-host.xml

<WindowsHost>
  <WindowsHost.MainMenu>
    <Menu HorizontalAlignment="Stretch">
      <Menu.Items>
        <MenuItem Type="Submenu" Title="_Web Service">
          <MenuItem.Items>
            <MenuItem Title="Time"></MenuItem>
            <MenuItem Title="Email"></MenuItem>
          </MenuItem.Items>
        </MenuItem>
      </Menu.Items>
    </Menu>
  </WindowsHost.MainMenu>
</WindowsHost>

Stack trace:

   at ConsoleFramework.Rendering.RenderingBuffer.SetOpacityRect(Int32 x, Int32 y, Int32 w, Int32 h, Int32 opacity) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\Rendering\RenderingBuffer.cs:line 204
   at ConsoleFramework.Controls.MenuItem.Popup.Render(RenderingBuffer buffer) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\Controls\Menu.cs:line 404
   at ConsoleFramework.Rendering.Renderer.processControl(Control control, List`1 revalidatedControls) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\Rendering\Renderer.cs:line 448
   at ConsoleFramework.Rendering.Renderer.updateLayout(Control control, List`1 revalidatedControls) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\Rendering\Renderer.cs:line 384
   at ConsoleFramework.Rendering.Renderer.invalidateLayout(List`1 affectedControls) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\Rendering\Renderer.cs:line 303
   at ConsoleFramework.Rendering.Renderer.UpdateLayout() in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\Rendering\Renderer.cs:line 134
   at ConsoleFramework.ConsoleApplication.runWindows(Control control) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\ConsoleApplication.cs:line 803
   at ConsoleFramework.ConsoleApplication.Run(Control control) in C:\Users\ktodyruik\Downloads\consoleframework-master\consoleframework-master\ConsoleFramework\ConsoleApplication.cs:line 387
   at HelloWorld.Program.Main(String[] args) in c:\projects\TUI\src\HelloWorld\Program.cs:line 26
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

screenshot

Examples project not buildable

5>C:\Users\david\S\consoleframework\Examples\Program.cs(122,25,122,30): error CS0012: The type 'ObservableList<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Binding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
5>C:\Users\david\S\consoleframework\Examples\Program.cs(123,25,123,30): error CS0012: The type 'ObservableList<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Binding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
5>C:\Users\david\S\consoleframework\Examples\Program.cs(153,29,153,34): error CS0012: The type 'ObservableList<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Binding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

phantom errors when running tests

Sometimes there are errors like this

Failed   Tests.LayoutTests.TestNormalMeasure3
Error Message:
 System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
Stack Trace:
   at System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion()
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at ConsoleFramework.Events.EventManager.AddHandler(Object target, RoutedEvent routedEvent, Delegate handler, Boolean handledEventsToo) in D:\all\ConsoleFramework\consoleframework\ConsoleFramework\Events\EventManager.cs:line 86
   at ConsoleFramework.Events.EventManager.AddHandler(Object target, RoutedEvent routedEvent, Delegate handler) in D:\all\ConsoleFramework\consoleframework\ConsoleFramework\Events\EventManager.cs:line 69
   at ConsoleFramework.Controls.Control.AddHandler(RoutedEvent routedEvent, Delegate delegate) in D:\all\ConsoleFramework\consoleframework\ConsoleFramework\Controls\Control.cs:line 197
   at ConsoleFramework.Controls.Control..ctor() in D:\all\ConsoleFramework\consoleframework\ConsoleFramework\Controls\Control.cs:line 416
   at Tests.LayoutTests.TestFinalControl..ctor()
   at Tests.LayoutTests.TestNormalMeasure3() in D:\all\ConsoleFramework\consoleframework\Tests\LayoutTests.cs:line 152

FindChildByName returns null when trying to get a MenuItem

Hi,

I'm trying to attach an event handler to an exit menu item. FindChildByName<> always returns null when I try to get the menu item.

Program.cs

WindowsHost windowsHost = (WindowsHost) ConsoleApplication.LoadFromXaml("HelloWorld.windows-host.xml", null);
            Window mainWindow = (Window) ConsoleApplication.LoadFromXaml("HelloWorld.main.xml", null);
            windowsHost.Show(mainWindow);
            MenuItem exit = windowsHost.MainMenu.FindChildByName<MenuItem>("exit");
           // exit is null

windows-host.xml

<WindowsHost>
  <WindowsHost.MainMenu>
    <Menu HorizontalAlignment="Stretch">
      <Menu.Items>
        <MenuItem Title="_Application" Type="Submenu" Gesture="Alt+F" Name="application">
          <MenuItem Title="_About" Name="about"/>
          <MenuItem Title="E_xit" TitleRight="Alt+X" Name="exit"/>
        </MenuItem>
      </Menu.Items>
    </Menu>
  </WindowsHost.MainMenu>
</WindowsHost>

Grid with Margin="1" causes InvalidOperationException

This assert fires:

Size desiredSize = MeasureOverride(frameworkAvailableSize);
if (desiredSize.Width == int.MaxValue || desiredSize.Height == int.MaxValue) {
    throw new InvalidOperationException("MeasureOverride should not return int.MaxValue even for" +
                                        "availableSize = {int.MaxValue, int.MaxValue} argument.");
}

need to fix measuring in Grid

Namespaced properties: cannot resolve type

Consider I have this XAML:

<c:Window xmlns:c="clr-namespace:ConsoleFramework.Controls;assembly=ConsoleFramework"
          xmlns:x="clr-namespace:ConsoleFramework.Xaml;assembly=ConsoleFramework"
                MinHeight="10" MinWidth="25"
                X="0" Y="0"
                Title="Refs">
    <c:ListBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <c:ListBox.Items>
            <string>xxxx</string>
        </c:ListBox.Items>
    </c:ListBox>
</c:Window>

When I try to load it, ConsoleFramework throws an exception:

Unhandled exception. System.InvalidOperationException: Cannot resolve type c:ListBox.Items
   at Xaml.XamlParser.resolveType(String name)
   at Xaml.XamlParser.createObject(String name)
   at Xaml.XamlParser.createFromXaml(String xaml, Object dataContext)
   at Xaml.XamlParser.CreateFromXaml[T](String xaml, Object dataContext, List`1 defaultNamespaces)
   at Fenrir.Ui.EntryPoint.loadFromXaml[a](String resourceName, RefsViewModel dataContext) in D:\X-Files\Projects\Fenrir\Fenrir.Ui\EntryPoint.fs:line 19
   at Fenrir.Ui.EntryPoint.run(String path) in D:\X-Files\Projects\Fenrir\Fenrir.Ui\EntryPoint.fs:line 28
   at Fenrir.Program.main(String[] argv) in D:\X-Files\Projects\Fenrir\Fenrir\Program.fs:line 187

It will work well if I write <ListBox.Items> instead of <c:ListBox.Items>, but this isn't right!

Problem with keyboard in powershell script

Hi, I run into problem with keyboard input when use library from powershell script. For example, here is my script:

function Get-ScriptPath
{
	Split-Path $myInvocation.ScriptName
}

$moduleName = "$(Get-ScriptPath)\Xaml.dll"
import-module $moduleName

$moduleName = "$(Get-ScriptPath)\ConsoleFramework.dll"
import-module $moduleName

$moduleName = "$(Get-ScriptPath)\Binding.dll"
import-module $moduleName

[ConsoleFramework.Controls.Window] $win = 
	[ConsoleFramework.Controls.Window][ConsoleFramework.ConsoleApplication]::LoadFromXaml("Layout.xml",$null)

[ConsoleFramework.Controls.WindowsHost] $windowsHost = [ConsoleFramework.Controls.WindowsHost][ConsoleFramework.ConsoleApplication]::LoadFromXaml("windows-host.xml", $null)

$windowsHost.show($win)

# [ConsoleFramework.ConsoleApplication]::Instance.Maximize()
[ConsoleFramework.ConsoleApplication]::Instance.run($windowsHost)


Running application can handle mouse input but not keyboard. What is could be? If you try to run my code you would get "Object reference not set to an instance of an object" exception because Assembly.GetEntryAssembly() returns null when it is called from unmanaged code (powershell)

problem with loading xaml

hi, i have a window from xaml all its fine but the controls will not be displayed:
`<my:Window Name="LoginWindow" Title="MissionPack Selection"
xmlns:x="http://consoleframework.org/xaml.xsd"
xmlns:my="clr-namespace:ConsoleFramework.Controls;assembly=ConsoleFramework"
xmlns:converters="clr-namespace:Binding.Converters;assembly=Binding"
xmlns:xaml="clr-namespace:ConsoleFramework.Xaml;assembly=ConsoleFramework"
MinWidth="50" MinHeight="50" X="50" >

<TextBox Text="Text"></TextBox>
<TextBox Text="Text"></TextBox>

<Button Caption="Long Button"></Button>
<ComboBox Name="cb"></ComboBox>

</my:Window>`

Multi-line text

Is it possible to display and/or edit multi-line text with one of the widgets?

Missing LICENSE.txt file

In README.md it says this is MIT/X11 licensed, but there isn't a corresponding LICENSE.txt file

.NET Core build

Any plans on making this compatible with the new .NET standard framework. I would like to use this in some of my .NET core apps...

TreeView: Disabled item can't be expanded with mouse or...

Regarding the Examples/TreeView: I don't know what the default behavior should be, but I suspect something is not quite right:
I can't select the General or My entries with the mouse by clicking (I can by scrolling the mouse wheel), but I can select them with the up/down keys.
But if they shouldn't be selectable they should at least expand the tree when clicked.

image

Has this great project been discontinued?

Unfortunately, the last commits of this really outstanding project are almost half a year ago. The project has a lot of potential and has some intuitive mechanisms. So I ask the question, is the project stopped or continued under another name? It would be a real shame if it doesn't go on here. Such a useful project must absolutely be continued and maintained.

Bug with ComboBox

Open ComboBox, by pressing mouse, and dont release the mouse button. Drag the mouse out of combobox, and there will be exception

if (opened) throw new InvalidOperationException("Assertion failed.");

Console buffer and screen size were not set

When I first tried the examples, because I have my windows console and buffer size set to different dimensions, the example applications were positioned incorrectly for full screen apps. For example, one example the panel was vertically centered, and was off my screen. Scrollling brought it in to view.

Trying my own console app, I added the following which set the windows console correctly:

        private static void Main(string[] args)
        {
            Console.SetWindowSize(80, 24);
            Console.SetBufferSize(80, 24);
            // etc...
        }

Shouldn't this be handled by the console framework when you run the console application?

Discussion: Xaml System?

Wow! What a super cool project. I am really impressed. I am curious about your Xaml system and if you are planning (or have considered) either making it its own standalone system, or maybe integrating another external system such as OmniXaml and/or Portable.Xaml?

In any case, great work here. 😄

styles

pls add styles with css

Multiple sln and csproj files

I was wondering, why are multiple sln and csproj files used instead of multiple configurations? In example, WIN32 is defined when using the normal slns. This could be moved to having Debug and DebugMono configurations for example, and each project would define WIN32 (for ConsoleFramework.csproj) for Debug, and not define it for DebugMono. It would make things way cleaner.

This would help with syncing projects and solutions automatically.

Is there anything else different than that define?

"Property xmlns not found" when trying to set root XML namespace

To simplify compatibility with existing XAML tooling (e.g. Rider XAML editor), I'd like to set my namespaces in the XAML file itself, for example:

<Window xmlns="clr-namespace:ConsoleFramework.Controls;assembly=ConsoleFramework"
                               MinHeight="10" MinWidth="25"
                               Title="Commits">
    <Panel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <TextBlock>Fenrir</TextBlock>
    </Panel>
</Window>

But this doesn't work: when I try to load this file, it throws an exception:

Unhandled exception. System.InvalidOperationException: Property xmlns not found.
   at Xaml.XamlParser.processAttribute(String attributePrefix, String attributeName, String attributeValue)
   at Xaml.XamlParser.createFromXaml(String xaml, Object dataContext)
   at Xaml.XamlParser.CreateFromXaml[T](String xaml, Object dataContext, List`1 defaultNamespaces)
   at Fenrir.Ui.EntryPoint.loadFromXaml[a](String resourceName, CommitsViewModel dataContext) in D:\X-Files\Projects\Fenrir\Fenrir.Ui\EntryPoint.fs:line 22
   at Fenrir.Ui.EntryPoint.run(String path) in D:\X-Files\Projects\Fenrir\Fenrir.Ui\EntryPoint.fs:line 29
   at Fenrir.Program.main(String[] argv) in D:\X-Files\Projects\Fenrir\Fenrir\Program.fs:line 187

I think that ConsoleFramework's XAML reader should respect well-known XML xmlns="" idiom.

Framework doesn't work in GitBash terminal emulator

Programs using the consoleframework can't run in terminal emulators, like GitBash command prompt. An Exception is thrown (invalid handle) at the start of the program.

Reproduction steps

  1. Have a small program, like:
using ConsoleFramework;
using ConsoleFramework.Controls;

namespace CrashTest
{
    class Program
    {
        static void Main(string[] args)
        {

            WindowsHost windowsHost = new WindowsHost();
            Window window = new Window();
            window.Content = new TextBlock
            {
                Text = "This will crash in Terminal Emulator"
            };
            windowsHost.Show(window);
            ConsoleApplication.Instance.Run(windowsHost);

        }
    }
}
  1. Compile it and try to execute it GitBash terminal ./CrashTest.exe

Result:

Unhandled exception. System.IO.IOException: Invalid handle.
   at System.ConsolePal.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
   at System.Console.get_WindowLeft()
   at ConsoleFramework.ConsoleApplication.runWindows(Control control)
   at ConsoleFramework.ConsoleApplication.Run(Control control)
   at CrashTest.Program.Main(String[] args) in Program.cs:line 18

Expected:

UI, like in Windows Command prompt (cmd.exe)

Gestures don't work

The examples application doesn't receive gestures. It seems there is a regression because the CodeProject source and binaries don't have this problem.
I'm testing on Windows 8.1 with Debug configuration.

Mouse interaction

I was wondering how do I achieve mouse interaction.
I have tried all included samples (WIndows Console), but I was unable to interact with TUI elements using mouse.

Does such possibility exists ?

MaxWidth игнорируется, если у родителя HorizontalAlignment=Stretch

Пытаюсь разобраться с багом, с которым столкнулся в CsConsoleFormat. Так как систему лейаута я копировал вашу — только выкинул ненужное из-за одноразовости вывода и навёл гламуру, — то попытался сравнить с вашей реализацией, авось в процессе наведения гламура что-то сломал. С удивлением обнаружил ту же самую проблему.

Собственно, если установить HorizontalAlignment=Stretch родителю, то свойства MaxWidth и MaxHeight, уменьшающие размер относительно возвращаемого из MeasureOverride желаемого размера, игнорируются. Попытался воспроизвести подобное в WPF, там ограничение на размер действует всегда, за границы велезти не получилось.

Так как вы в этих лейаутах разбираетесь на порядок лучше меня, то хотелось бы услышать ваше мнение по поводу этого. Это баг?

Воспроизведение:

using ConsoleFramework;
using ConsoleFramework.Controls;
using ConsoleFramework.Core;
using ConsoleFramework.Native;
using ConsoleFramework.Rendering;

namespace ConsoleFrameworkApp
{
    class Program
    {
        static void Main()
        {
            var window = new Panel {
                Width = 7,
                Height = 2,
                HorizontalAlignment = HorizontalAlignment.Left,
                XChildren = {
                    new Fill {
                        HorizontalAlignment = HorizontalAlignment.Stretch,
                        Char = '_',
                        Attr = Attr.FOREGROUND_BLUE | Attr.FOREGROUND_INTENSITY | Attr.BACKGROUND_BLUE,
                        XChildren = {
                            new FillAlphabet {
                                AlphaWidth = 3,
                                AlphaHeight = 2,
                                MaxWidth = 2,
                                HorizontalAlignment = HorizontalAlignment.Left,
                                Attr = Attr.FOREGROUND_RED | Attr.FOREGROUND_INTENSITY | Attr.BACKGROUND_RED,
                            }
                        }
                    }
                }
            };
            ConsoleApplication.Instance.Run(window);
        }
    }

    class Fill : Panel
    {
        public char Char { get; set; }
        public Attr Attr { get; set; }

        public override void Render(RenderingBuffer buffer)
        {
            buffer.FillRectangle(0, 0, ActualWidth, ActualHeight, Char, Attr);
        }
    }

    class FillAlphabet : Fill
    {
        public int AlphaWidth { get; set; }
        public int AlphaHeight { get; set; }

        public FillAlphabet()
        {
            Char = '-';
        }

        protected override Size MeasureOverride(Size availableSize) => new Size(AlphaWidth, AlphaHeight);

        public override void Render(RenderingBuffer buffer)
        {
            base.Render(buffer);
            char nextChar = 'a';
            for (int y = 0; y < AlphaHeight; y++)
                for (int x = 0; x < AlphaWidth; x++)
                    buffer.SetPixel(x, y, nextChar++, Attr);
        }
    }
}

Ожидаемое:

ab_____
de_____

Действительное:

abc____
def____

Аналогичный тест из CsConsoleFormat.

Create a persistent window.

Is possible create and show a window that user can't close (allow close only by code)? like a loading screen, keep open when is loading something and close if is done.

Like windows forms event FormClosingEventArgs (e.Cancel = true keeps form opened)

Binding to ListBox.SelectedItemIndex

Currently, it's impossible to bind to a SelectedItemIndex property of ListBox, because it only raises SelectedItemIndexChanged event on change, and doesn't raise PropertyChanged.

I think that it should be possible to bind to it by default.

Programmatical (vs XAML) example?

All examples I saw so far use XAML files. Is there example how to code UI programmatically, by instantiate objects and calling methods?

NuGet Package

Does a NuGet package exist for this project? Googled around for stuff like "ConsoleFramework nuget" and nothing came up.

It's the de-facto way to include external dependencies and necessary for use with e.g. .net core.

Scheduling tasks before `ConsoleApplication` has been started

I have a couple of view models that start to execute some asynchronous tasks in their constructors (or as part of their initialization). For an example, let's consider something like this:

MyWindow.xaml:

<c:Window xmlns:c="clr-namespace:ConsoleFramework.Controls;assembly=ConsoleFramework"
          xmlns:x="clr-namespace:ConsoleFramework.Xaml;assembly=ConsoleFramework"
          xmlns:controls="clr-namespace:Fenrir.Ui.Framework.Controls;assembly=Fenrir.Ui.Framework"
          MinHeight="10" MinWidth="25"
          X="0" Y="0"
          Title="Wnd">
    <c:ListBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
               Items="{x:Binding ItemList, Mode=OneWay}" />
</c:Window>

Program.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Binding.Observables;
using ConsoleFramework;
using ConsoleFramework.Controls;

namespace ConsoleApp2
{
    public class MyViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public ObservableList<string> ItemList { get; } = new ObservableList<string>(new List<string>());

        public MyViewModel()
        {
            // Load initial data
            Task.Run(async () =>
            {
                ConsoleApplication.Instance.Post(() =>
                {
                    ItemList.Add("a");
                    ItemList.Add("b");
                    ItemList.Add("c");
                });
            });
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var host = new WindowsHost();
            var window = (Window) ConsoleApplication.LoadFromXaml(
                "ConsoleApp2.MyWindow.xaml",
                new MyViewModel());
            host.Show(window);
            ConsoleApplication.Instance.Run(host);
        }
    }
}

Here, I have a data source that's populated asynchronously at the application start. It may load data from network or whatever, and then delegates the UI-related task to UI thread, in a classic fashion.

The problem is that it doesn't work: most of the time, at the moment I call ConsoleApplication.Instance.Post, the console application hasn't started yet, and thus it rejects my task:

public void Post( Action action ) {
// If run loop is not started, nothing to do
if ( !this.running ) {
return;
}

How do I solve this problem?

I've tried to lazily start the task in the ItemList accessor:

        private ObservableList<string> _itemList;
        public ObservableList<string> ItemList
        {
            get
            {
                if (_itemList == null)
                {
                    _itemList = new ObservableList<string>(new List<string>());
                    // Load initial data
                    Task.Run(async () =>
                    {
                        ConsoleApplication.Instance.Post(() =>
                        {
                            ItemList.Add("a");
                            ItemList.Add("b");
                            ItemList.Add("c");
                        });
                    });
                }
                 return _itemList;
            }
        }

This doesn't work because the binding calls the accessor before the application hass been started, in the LoadFromXaml.

I haven't found any reliable way to inject my code into the application event queue, except a very hacky one. Since I know that the application will activate every window I Show, I could do something like this:

var viewModel = new MyViewModel();
var window = (Window) ConsoleApplication.LoadFromXaml(
    "ConsoleApp2.MyWindow.xaml",
    viewModel);
host.Show(window);
EventHandler oneTimeHandler = null;
oneTimeHandler = (_, __) =>
{
    Task.Run(async () =>
    {
        ConsoleApplication.Instance.Post(() =>
        {
            viewModel.ItemList.Add("a");
            viewModel.ItemList.Add("b");
            viewModel.ItemList.Add("c");
        });
    });
    EventManager.RemoveHandler(window, Window.ActivatedEvent, oneTimeHandler);
};

EventManager.AddHandler(window, Window.ActivatedEvent, oneTimeHandler);

This is, obviously, very hacky and uncool (but it works though).

If only ConsoleApplication had a way to schedule task before it has been started, or a legal way to know when it has been started… That way, I could wait for an event or whatever in my custom synchronization context routine.

So, here's my suggestion:

  1. Make ConsoleApplication.RunOnUiThread to return a bool, so the caller could know when their action was rejected from running by the application. Or even throw an exception.
  2. Perform the same change with ConsoleApplication.Post(Action action)
  3. Add an overload ConsoleApplication.Post(Action action, bool evenIfNotStarted). If evenIfNotStarted= true, then the application should always queue the action, even if it isn't running yet.
  4. Since the user now may try calling Post(smth, evenIfNotStarted: true) even after Dispose, add a guard: all the queue methods should throw exceptions if called after Dispose.
  5. Since it'll be possible to create a memory leak by adding queue methods and then calling Dispose without starting the application (which is theoretically possible even before the proposed changes), Dispose should empty the action queue.
  6. Just as a quality-of-life design improvement, I suggest Post(Action action, TimeSpan delay) to take an additional (optional) callback argument that will be called in case the action was rejected (either in case the application wasn't running or it was disposed at the time the callback has been dispatched).
  7. Make a public member of private volatile bool running, so the callers will be able to insect the application state.

@elw00d, do these changes look okay to you? I'm ready to send a PR with these improvements and a decent test suite. I believe it may be done without breaking the source compatibility (and I may work on binary compatibility, too, but I don't think it's necessary at this point though).

Windows: disable QUICK_EDIT_MODE on start

Currently, Windows 10 console has ENABLE_QUICK_EDIT_MODE flag by default which messes up any mouse interactions.

I suggest ConsoleFramework should disable this mode when starting. I've done it via this quick F# snippet:

let private initializeWindows() =
    let stdin = Windows.getStdInHandle()
    let consoleMode = Windows.getConsoleMode stdin
    if consoleMode &&& Windows.Constants.ENABLE_QUICK_EDIT_MODE <> 0u then
        let newMode =
            (consoleMode ||| Windows.Constants.ENABLE_EXTENDED_FLAGS) &&& ~~~Windows.Constants.ENABLE_QUICK_EDIT_MODE
        Windows.setConsoleMode stdin newMode

(essentially, you should just call SetConsoleMode(stdin, (mode | ENABLE_EXTENDED_FLAGS) & ~ENABLE_QUICK_EDIT_MODE))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.