c# - 用于生成显示 x 秒的初始屏幕的最小独立 WPF/C#

标签 c# splash-screen csc

我想知道,为什么在下面的代码中我的启动画面在 x 秒后没有消失?在 C# 中,我启动了一个等待 x 秒的线程,然后在屏幕上显示时尝试将 close() 分派(dispatch)到启动窗口。

// FILE: splashy.cs
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Windows;
using System.Windows.Markup;
using System.Threading;

namespace Splashy
{
    class MySplash
    {
        Window win;

        public void Show()
        {
            var mem     = new MemoryStream(
                            ASCIIEncoding.UTF8.GetBytes(xmlstr));

            win         = (Window)XamlReader.Load(mem);
            (new Thread(CloseIt)).Start();
            win.Show();
        }

        public void CloseIt() {
            Thread.Sleep(4*1000);
            //MessageBox.Show("CLOSE");
            win.Dispatcher.Invoke(() => win.Close());
        }

        static string xmlstr = @"
<Window
  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
  xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  Name='WindowSplash'
  Title='My Splash Window...'
  WindowStyle='None'
  WindowStartupLocation='CenterScreen'
  Background='White'
  ShowInTaskbar ='true'
  Width='350' Height='130'
  ResizeMode = 'NoResize' >

<Window.Resources>
    <Style TargetType='{x:Type Label}'>
            <Setter Property='FontFamily' Value='Consolas'/>
            <Setter Property='Background' Value='Blue'/>
            <Setter Property='Foreground' Value='AntiqueWhite'/>
    </Style>
</Window.Resources>

<Grid>

<Grid.RowDefinitions>
    <RowDefinition Height='Auto'/>
    <RowDefinition Height='*'/>
    <RowDefinition Height='Auto'/>
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
    <ColumnDefinition Width='Auto'/>
    <ColumnDefinition Width='*'/>
</Grid.ColumnDefinitions>

<Label
    Grid.ColumnSpan='2'
    Grid.Row='0'
    Content='MyApplication 1.0'
    FontWeight='Bold'
    FontFamily='Consolas'
    Background='AntiqueWhite'
    Foreground='Black'/>

<Label
    Grid.ColumnSpan='2'
    Grid.Row='2'
    Content=''
    FontWeight='Bold'
    FontFamily='Consolas'
    Background='AntiqueWhite'
    Foreground='Black'/>


<Label
    Grid.Column='0'
    Grid.Row='1'
    FontFamily='Webdings' Content='&#xc2;' FontSize='80' />

<StackPanel
    Grid.Row='1'
    Grid.Column='1'
    Background='Blue'
    >
    <Label Content='Programmer: John Smith'/>
    <Label Content='Email:      john.smith@gmail.com'/>
    <Label Content='Dates:      2017'/>
</StackPanel>

</Grid>

</Window>
";

    } //end-class

    class MyApp 
    {
        [STAThread]
        static void Main(string[] args)
        {
            (new MySplash()).Show();
        }
    } //end-class
} //end-namespace

下面是我的 csc.exe 命令行在控制台模式 C++ 应用程序内部从 system(...) 编译以上 C# 代码的示例:

C:\WINDOWS\Microsoft.Net\Framework64\v4.0.30319\csc.exe 
/out:splashy.exe 
/nologo  
/target:winexe 
splashy.cs 
/reference:"C:\WINDOWS\Microsoft.Net\Framework64\v4.0.30319\WPF\presentationframework.dll" 
/reference:"C:\WINDOWS\Microsoft.Net\Framework64\v4.0.30319\WPF\windowsbase.dll" 
/reference:"C:\WINDOWS\Microsoft.Net\Framework64\v4.0.30319\WPF\presentationcore.dll" 
/reference:"C:\WINDOWS\Microsoft.Net\Framework64\v4.0.30319\System.Xaml.dll"

最佳答案

您的程序不执行消息队列和向窗口发送窗口消息的操作。因此,您尝试关闭窗口(向窗口发送 WM_CLOSE 消息)无效。

在您的示例中解决此问题的最简单方法是使用 win.ShowDialog() 而不是 win.Show()ShowDialog() 方法取代任何已在运行的消息泵循环,将其替换为自己的循环(它这样做是为了拦截不应发送到其他窗口的用户输入消息,同时模态对话框已启动)。但它不需要已经存在消息泵循环,它运行的循环足以接收您的 WM_CLOSE 并关闭窗口。

如果您想做得更恰当,您可以将一个Application 对象添加到您的示例中并调用Application.Run() 来提供消息泵循环。如果您在某个时候期望需要显示多个窗口或以其他方式需要非模态 UI,您可能想要这样做。

关于c# - 用于生成显示 x 秒的初始屏幕的最小独立 WPF/C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46334335/

相关文章:

c# - 等待异步 API 的 Specflow 步骤

java - 在我的 Android 应用程序中未找到类异常

c# - 如何编译特定语言版本的C#

c# - PDB 文件在第二次编译时变大,然后保持相同大小

c# - C# CodeDom 在 csc.exe 中导致堆栈溢出 (CS1647) 的解决方法?

c# - 使用 Entity Framework 进行级联插入

c# - 操作超时错误

c# - Linq 查询等效于存在多个条件

iOS PWA 闪屏?

android - 当我为启动屏幕创建 9 个补丁图像时,它对于大型设备来说太小了