Как я могу сделать хороший экран-заставку, который выполняет два действия одновременно? - PullRequest
0 голосов
/ 01 июля 2019

В настоящее время я пытаюсь создать заставку, однако я не могу выполнить несколько задач для настройки сразу.

Я пытался использовать класс BackgroundWorker, а также класс Thread, и, похоже, ни один из них не работает.

В файле app.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
{
    var splashScreen = new Windows.Splash();
    splashScreen.Show();

    base.OnStartup(e);

    splashScreen.Close();
}

В файле splashScreen.xaml.cs:

public Splash()
{
    InitializeComponent();
    DataContext = this;

    changeLoadingTxtTimer = new System.Timers.Timer(2000);
    changeLoadingTxtTimer.Elapsed += Timer_Elapsed;

    backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += D_DoWork;
    backgroundWorker.RunWorkerAsync();

    changeLoadingTxtTimer.Start();
}

private void D_DoWork(object sender, DoWorkEventArgs e) { UpdateDatabase(); }

private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    LoadingTxtValue = LoadingTxts[rd.Next(0, LoadingTxts.Length - 1)];

    if (!backgroundWorker.IsBusy)
        changeLoadingTxtTimer.Stop();
    }
}

Я ожидаю, что при работе BackgroundWorker загрузка текста будет меняться каждые 2 секунды, но в действительности происходит то, что BackgroundWorker завершает свою работу, а заставка закрывается.

Ответы [ 3 ]

1 голос
/ 01 июля 2019

App.xaml

Удаление записи StartupUri

<Application
      x:Class="WpfSplashApp.App"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="clr-namespace:WpfSplashApp">
    <Application.Resources />
</Application>

App.xaml.cs

public partial class App : Application
{
    public App()
    {
        Startup += App_Startup;
    }

    private async void App_Startup( object sender, StartupEventArgs e )
    {
        var splash = new SplashWindow();
        splash.Show();

        await InitializeAsync();

        var main = new MainWindow();
        main.Show();
        MainWindow = main;

        splash.Close();            
    }

    private Task InitializeAsync()
    {
        // Do some ASYNC initialization 
        return Task.Delay( 5000 );
    }
}
0 голосов
/ 01 июля 2019

Я думаю, что вы должны выполнить инициализацию основного вида внутри самого основного вида. Как только основной вид инициализируется, он вызывает соответствующее событие. Затем вы реагируете на это событие, закрывая заставку и показывая основной вид. Поэтому единственная задача заставки - отображать заставку.

App.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    this.splashScreen = new Windows.Splash();
    this.splashScreen.Show();

    // Initialize the main application view
    this.MainWindow = new MainWindow();
    this.MainWindow.Initialized += ShowMainWindow;
    this.MainWindow.Initialize();
}

private void ShowMainWindow(object sender, EventArgs e)
{
    this.splashScreen.CloseSplashScreen();
    this.MainWindow.Show();
}

Splash.xaml.cs:

public Splash()
{
    InitializeComponent();
    this.DataContext = this;

    this.changeLoadingTxtTimer = new System.Timers.Timer(2000);
    this.changeLoadingTxtTimer.Elapsed += Timer_Elapsed;
    this.changeLoadingTxtTimer.Start();
}

public void CloseSplashScreen()
{
    this.changeLoadingTxtTimer.Stop();
    this.changeLoadingTxtTimer.Dispose();
    Close();
}

private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    this.Dispatcher.Invoke(() => this.LoadingTxtValue = this.LoadingTxts[rd.Next(0, this.LoadingTxts.Length - 1)]);
}
0 голосов
/ 01 июля 2019

Если я правильно понимаю, у вас есть список строк:

var TextList = new[] {"Text 1", "Text 2", "Text 3"};

И пока выполняется фоновая работа, вы хотите, чтобы эти строки появлялись каждые 2 секунды. Я понятия не имею, что делает ваш фоновый работник, но я предполагаю, что вы знаете, что вы делаете с этим. Я также предполагаю, что ваш Textblock привязан к строковому свойству с именем LoadingTxtValue на вашем контроле.

На мой взгляд, лучшим инструментом для этой работы является Reactive . Добавьте ссылку на System.Reactive и используйте следующее сразу после RunWorkerAsync.

Observable.Timer(TimeSpan.FromSeconds(2))
.Subscribe(
    t => App.Current.Dispatcher.Invoke(new Action(() => LoadingTxtValue = TextList[t])));

Я надеюсь, что это может решить вашу проблему.

...