Pull to refresh

Comments 15

Интересно, то что эта статья видна в списке английских статей — это баг или фича?
спасибо
почему-то дефолтный был англ, вроде поправил
Добавим методу main атрибут [STAThread]
Зачем?

А действительно, зачем? Из приведенной ссылки это не слишком понятно.

Если мы теперь вызовем на окне метод Show(), оно тут же схлопнется, а так как нам бы хотелось на него смотреть все время, то это окно нужно запихнуть в контейнер, который поддерживает весь жизненный цикл.

Почему вам не подошел Window.ShowDialog()?
он захватывает фокус, а я хотел добиться стандартного поведения окна
Думаю, я внес уточнения и теперь «зачем» стал куда более понятным
Окно отображается, а после закрывается т.к. выполнение кода заканчивается и окно закрывается, и,! внезапно!, нужен цикл обработки событий. (Ну или просто Thread.Sleep(10000) воткнуть если нужно только показать окно). Кроме того Ваш код нерабочий: Task.Delay(1000); без Wait ничего не ждет, а Application.Current.Shutdown(); свалится с исключением межпоточного взаимодействия — даже проверил специально. Если хотите и окно и консоль — сделайте оконное приложение и в свойствах проекта выберите тип «Консольное приложение».
Спастбо, вы правы, а я при написании поста допустил грубую ошибку по причине версионирования
Так, наверное, было бы интереснее:
using System.Xml;
using System.Windows.Markup;

namespace ConsoleApplication1
{
    internal class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
            XmlTextReader r = new XmlTextReader("MyWindow.xaml");
            
            var app = new Application();            
            app.MainWindow = XamlReader.Load(r) as Window;
            app.MainWindow.Show();
// ... etc

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="MyWindow" Height="450" Width="800">
    <Grid>
        <Label Content="Label" HorizontalAlignment="Left" Margin="80,53,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Width="127">
        </Label>
        <Button Content="Button" HorizontalAlignment="Left" Height="40" Margin="80,105,0,0" VerticalAlignment="Top" Width="144"/>
<!-- и т.д. по вкусу -->
    </Grid>
</Window>

Консольное приложение для винды? Зачем?

Вот так не проще ли?


app.Dispatcher.InvokeAsync((Action)(async () => {
    await Task.Delay(1000);
    app.Shutdown();
}));
app.Run(win);
Как-то переусложнено. Мы готовим обычный WPF класс, потом
var thread = new Thread(() =>
                   {
                        mywindow = new MyWindow();
                        mywindow.Show();
                        Dispatcher.Run();
                   });
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
...
var dispatcher = Dispatcher.FromThread(thread);
dispatcher.InvokeShutdown();


Никаких STA на главном потоке, никаких связей с Application.

Так лучше не делать, Dispatcher.FromThread может вернуть null если не повезет с порядком выполнения потоков.

Это упрощенный код. Конечно, у нас есть доп. проверки.
Тут не доп. проверка нужна, а доп. синхронизация…
Нужно дождаться создания диспетчера в созданном потоке, после этого вызов Dispatcher.FromThread уже не вернёт null
Sign up to leave a comment.

Articles

Change theme settings