Однажды мне нужно было открыть окно из консольного приложения.
Я хотел сделать это с помощью wpf, но информации, разбросанной в Интернете, было недостаточно, поэтому я решил как-то систематизировать и представить этот небольшой урок.
Давайте создадим обычное консольное приложение, используя .
net framework.
Теперь вам нужно добавить зависимости: WindowsBase, PresentationCore, PresentationFramework.
Добавим класс для нашего окна, унаследовав его от стандартных окон Windows.
Добавим атрибут [STAThread] в основной метод. За что STAThreadAttribute по сути является требованием для обмена сообщениями Windows Messaging Server с компонентами COM. Подробнее.public class MyWindow : Window{}
[STAThread]
public static void Main(string[] args){}
Теперь создадим наше окно:
[STAThread]
public static void Main(string[] args)
{
var win = new MyWindow { Width = 350, Height = 350};
var grid = new Grid();
var text = new TextBox {Text = "my text"};
grid.Children.Add(text);
win.Content = grid;
}
Если мы сейчас вызовем метод Show() у окна, оно сразу же схлопнется, а поскольку нам хотелось бы смотреть на него постоянно, то это окно нужно поместить в контейнер, поддерживающий весь жизненный цикл.
app.MainWindow = win;
app.MainWindow.Show();
app.Run();
Мы отобразили окно, и это приятно, но закрыть его из кода не так-то просто: метод Run() представляет собой бесконечный цикл, а остановить приложение можно только из того же потока, в котором оно было вызвано.
Выход:
Task.Run(async () =>
{
await Task.Delay(1000);
app.Dispatcher.Invoke((Action) delegate { app.Shutdown(); });
});
;
Тогда весь метод будет выглядеть так Так.
[STAThread]
public static void Main(string[] args)
{
var app = new Application();
var win = new MyWindow { Width = 350, Height = 350};
var grid = new Grid();
var text = new TextBox {Text = "my text"};
grid.Children.Add(text);
win.Content = grid;
app.MainWindow = win;
app.MainWindow.Show();
Task.Run(async () =>
{
await Task.Delay(1000);
app.Dispatcher.Invoke((Action) delegate { app.Shutdown(); });
});
app.Run();
}
и вот источник
Неплохим решением было бы не создавать наше окно из кода, а перейти на более привычный xaml.
Для этого добавьте зависимость System.Xml.
И мы создаем документ xaml. <Window
xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml "
xmlns:d="http://schemas.microsoft.com/expression/blend/2008 "
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006 "
xmlns:local="clr-namespace:ConsoleApplication1 "
mc:Ignorable="d "
Title="Мое окно" Height="450" Width="800">
<Grid>
<Label Content="Этикетка" />
</Grid>
</Window>
Теперь загружаем данные из файла.
XmlTextReader r = new XmlTextReader("MyWin.xaml");
var win = XamlReader.Load(r) as Window;
И в этой версии финальный Main выглядит так Так.
[STAThread]
public static void Main(string[] args)
{
var app = new Application();
XmlTextReader r = new XmlTextReader("MyWin.xaml");
var win = XamlReader.Load(r) as Window;
app.MainWindow = win;
app.MainWindow.Show();
Task.Run(async () =>
{
await Task.Delay(1000);
app.Dispatcher.Invoke((Action) delegate { app.Shutdown(); });
});
app.Run();
}
P.S.
Спасибо #чату на тг и пользователю Юрий .
Теги: #Разработка Windows #C++ #.
NET #console #wpf
-
Куда Пропали Все Сайты С Веб-Контентом?
19 Oct, 24 -
The Old Reader Перестает Быть Общедоступным
19 Oct, 24 -
На Станции Метро Окажут Онлайн-Помощь
19 Oct, 24