2017-09-21 44 views
2

我在想,爲什麼我的啓動畫面在下面的代碼中x秒後不消失?在C#中,我啓動一個線程,等待x秒,然後嘗試將close()發送到啓動窗口,同時將其顯示在屏幕上。最小自包含WPF/C#用於生成啓動畫面,顯示x秒

// 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:  [email protected]'/> 
    <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#代碼編譯(...)控制檯模式下的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" 

回答

1

程序的確沒什麼泵送消息隊列並將窗口消息分派給窗口。因此,您關閉窗口的操作將無效,該窗口將發送WM_CLOSE消息到窗口。

解決這個在您的例子是使用win.ShowDialog()而不是win.Show()最簡單的方法。 ShowDialog()方法取代任何消息泵循環已經運行,用它自己的替代它(這樣做是爲了攔截在模態對話框啓動時不應該分派給其他窗口的用戶輸入消息)。但它並不要求已經有消息泵循環,它所運行的循環就足以接收你的WM_CLOSE並關閉窗口。

如果您想更正確地做到這一點,可以將Application對象添加到您的示例中,並調用Application.Run()來提供消息泵循環。如果您在某些時候希望顯示多個窗口或需要非模態UI,則可能需要執行此操作。

+0

謝謝!重寫並添加「Application.Run(win)」後,它可以正常工作。 –

+0

@Bill:看着你的問題,看起來你從未接受任何提供給你的答案。您可能想閱讀[當某人回答我的問題時該怎麼辦?](https://stackoverflow.com/help/someone-answers):) –

0

這些是爲我工作了修改:

// 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 Window CreateWindow() 
     { 
      var mem  = new MemoryStream(
           ASCIIEncoding.UTF8.GetBytes(xmlstr)); 
      win   = (Window)XamlReader.Load(mem); 
      (new Thread(CloseIt)).Start(); 
      return win; 
     } 

     public void CloseIt() { 
      Thread.Sleep(2000); 
      Application.Current.Dispatcher.Invoke(() => { 
       win.Close(); 
      }); 
     } 

     [STAThread] 
     static void Main(string[] args) 
     { 
      Application app = new Application(); 
      MySplash splash = new MySplash(); 
      Window  win = splash.CreateWindow(); 
      app.Run(win); 
     } 

     static string xmlstr = @" 
      <Windows ...> 
      <!-- ... Omitted to save space ... --> 
      <Window/> 
     "; 

    } //end-class 
} //end-namespace