WPF启动屏幕Windows

5
我需要一个带透明度的PNG作为启动画面。图像的透明部分应该是清晰的,这样用户就可以看到它后面的任何窗口(或桌面)。
我还需要显示启动画面5秒钟(合同明确规定为5秒),不能更短。我知道VS 2010中的构建属性,但启动画面来去太快了(少于5秒)。
我该怎么做才能让它停留5秒钟(大约)?

3
Thread.Sleep(5000); 是什么意思? :) (翻译说明:尽可能准确地翻译了原文,并在最后使用了“:)”表示问句的语气,但没有写解释或其他内容) - Renatas M.
对于透明的PNG图像,您需要使用类似Photoshop或Illustrator的软件来保存alpha通道信息。 - Stonetip
关于启动画面,您可能需要添加某种自定义弹出窗口。如果用户可以单击复选框以不必再次显示它,那就太好了。但我怀疑合同不允许这样做!似乎有太多公司宁愿排斥用户,只要他们能得到营销收益。 - Stonetip
我喜欢Thread.Sleep的想法。你有任何示例代码来说明吗? - Cocoa Dev
2
如果更喜欢计时器而不是线程休眠 - Afnan Bashir
@Cocoa Dev 在表单加载后或关闭前添加睡眠。此外,这里有一个简单的透明启动屏示例,但它是为winform设计的。 - Renatas M.
5个回答

6
我曾经遇到过类似的问题,在一个WPF项目中无法使用内置的启动屏选项。
该项目现在是开源的,你可以在这里查看:https://code.google.com/p/theomniscientchimp/
它是一个自动更新程序(我想你可能不需要其中的一些东西)。
以下是你所需的最少内容:
WPF端:
<Window x:Class="TheOmniscientChimp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CustomXaml"
        Icon="SC2_Replay_Monkey.ico"
        Title="MainWindow" Height="256" Width="456" Background="#00005555" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen" >
        <Grid Width="Auto">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />           
        </Grid.RowDefinitions>
        <Image Name="splashScreenImage" Stretch="Fill" Grid.Row="0" />
    </Grid>
</Window>

C#端(后端代码):

/// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            BitmapImage splashScreenImageSource = new BitmapImage();
            splashScreenImageSource.BeginInit();
            splashScreenImageSource.UriSource = new Uri("Your_Image.png", UriKind.Relative);
            splashScreenImageSource.EndInit();

            splashScreenImage.Source = splashScreenImageSource;
        }

        public void AsynchronousExit()
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.RunWorkerAsync();
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            //Makes the thread wait for 5s before exiting.
            Thread.Sleep(5000);
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Environment.Exit(0);
        }
    }

告诉我如果你需要帮助进行调整。
FB。

这段代码是属于MailApplication的还是我需要创建一个新的WPF窗口并将代码(XAML/C#)添加到新窗口中? - Cocoa Dev
我把我的放在了一个独立的项目中,但你也可以把它放在你的主应用程序中,在应用程序启动之前调用它。 - Louis Kottmann

5
如果我需要这样做,我会添加一个窗口并设置其属性 AllowsTransparency = true;。在加载所有表单之前,将其设置为启动状态,这可以通过修改 App.xml 并设置 Startup="Application_Startup 来完成。
要禁用顶部默认控件,您需要设置 WindowStyle = none,并在其代码中进行操作。
private void Application_Startup(object sender, StartupEventArgs e)
        {
            MainWindow mn = new MainWindow();
            mn.ShowDialog();          
        }

使用计时器来实现您想要的任何操作。

private DispatcherTimer timer;
timer = new DispatcherTimer();
            timer.Tick += new EventHandler(timer_Tick);
            timer.Interval = TimeSpan.FromMilliseconds(5000);
            timer.IsEnabled = true;

void timer_Tick(object sender, EventArgs e)
        {
///Close your window here
}

希望这能帮助到您。

1

我曾经遇到过同样的问题,但实际上解决起来非常容易,无需任何特殊操作:

  1. 将您的图像添加到主项目中,并将构建属性设置为“启动画面”。

  2. 在应用程序主窗口的构造函数中,在InitializeComponents()调用之前添加Thread.Sleep(5000)。

这将延迟加载您的主WPF窗口,启动画面将保持至少加载时间+睡眠时间,然后主窗口弹出并关闭启动画面。


0

你可能需要做类似于WinForms的事情。启动一个新线程并在该线程上启动Wpf应用程序。在WinForms中,您可以使用System.Windows.Forms.Application.Run(new SplashForm())来实现此目的。在Wpf中应该有类似的方法。

编辑: 我找到了这个链接,所以它应该可以工作。 http://msdn.microsoft.com/en-us/library/ms597011.aspx

关键是要在单独的线程上执行此操作。应用程序启动的线程已经绑定到一个WPF应用程序,而您希望您的闪屏基本上成为自己的GUI。然后,该窗体可以具有定时器,使其关闭自身,这应该自动终止此其他应用程序。


0
如果您想使用启动画面窗口并使用后台工作器,那么您的主要代码将变得更加复杂,而这并不是必要的。解决方案是在主UI线程中以普通同步代码风格编写主要代码,同时显示启动画面窗口,直到您关闭它,并且您可以发送更新以更改启动画面加载文本或进度条。
SplashWindow window = null;


var thread = new Thread(new ThreadStart(() =>
{
    Debug.Print("Thread begin");
    window = new SplashWindow();
    window.ShowDialog();
}));

thread.Name = "RunSplashWindow";
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();

Debug.Print("App begin");

Thread.Sleep(1000);

if (window != null)
{
    window.Dispatcher.BeginInvoke(new Del(() => {
        window.SetHeader("Running...");
    }), new object[0]);
}

Thread.Sleep(1000);

for (int i = 1; i <= 100; i++)
{
    if (window != null)
        {
             window.Dispatcher.BeginInvoke(new Del(() =>
             {
             window.SetProgress((double)i);
        }), new object[0]);
    }

    Thread.Sleep(10);
}

Thread.Sleep(1000);

Debug.Print("App end");

if (window != null)
{
    window.Dispatcher.BeginInvoke(new Del(() =>
    {
        window.Close();
    }), new object[0]);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接