Использование окна в качестве экрана загрузки
Я не смог найти что-то напрямую, чтобы решить эту проблему. Я пытаюсь сделать анимированный GIF-файл в качестве экрана загрузки для нескольких мест в моей программе, где время загрузки слишком долго.
Я запустил его в стартапе, но как только я пытаюсь использовать его снова, он вылетает из моей программы. Я никогда полностью не понимал всю многопоточность, поэтому что-то могло быть не так в моем коде.
[РЕДАКТИРОВАТЬ] То, что я хочу, чтобы экран загрузки происходил, когда запущен тяжелый метод, скажем, когда он получает все данные из базы данных или просто простой Thread.Sleep(####), и в этот момент я хочу динамический экран-заставка для запуска, где этот экран является моим вторым окном с анимированным GIF на нем. У меня есть окно и работает GIF.
Windows, которую я собираюсь пересечь
- MainWindow.xaml
- Loading.xaml
- App.xaml
Loading.xaml
Единственное, что есть на этой странице - это анимированный GIF-файл с использованием пакета WpfAnimatedGif. и остальная часть окна прозрачна.
public partial class Loading : Window, ISplashScreen
{
public Loading()
{
InitializeComponent();
}
public void LoadStart()
{
Dispatcher.Invoke((Action)delegate()
{
//this.UpdateMessageTextBox.Text = message;
});
}
public void LoadComplete()
{
Dispatcher.InvokeShutdown();
}
}
public interface ISplashScreen
{
void LoadStart();
void LoadComplete();
}
}
App.xaml
public partial class App : Application
{
public static ISplashScreen splashScreen;
private ManualResetEvent ResetSplashCreated;
private Thread SplashThread;
protected override void OnStartup(StartupEventArgs e)
{
// ManualResetEvent acts as a block. It waits for a signal to be set.
ResetSplashCreated = new ManualResetEvent(false);
// Create a new thread for the splash screen to run on
SplashThread = new Thread(ShowSplash);
SplashThread.SetApartmentState(ApartmentState.STA);
SplashThread.IsBackground = true;
SplashThread.Name = "Splash Screen";
SplashThread.Start();
// Wait for the blocker to be signaled before continuing. This is essentially the same as: while(ResetSplashCreated.NotSet) {}
ResetSplashCreated.WaitOne();
base.OnStartup(e);
}
private void ShowSplash()
{
// Create the window
Loading animatedSplashScreenWindow = new Loading();
splashScreen = animatedSplashScreenWindow;
// Show it
animatedSplashScreenWindow.Show();
// Now that the window is created, allow the rest of the startup to run
ResetSplashCreated.Set();
System.Windows.Threading.Dispatcher.Run();
}
}
}
MainWindow.xaml
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Action that takes time here
App.splashScreen.LoadComplete();
}
private void _btnVisUKategorier_Click(object sender, RoutedEventArgs e)
{
App.splashScreen.LoadStart();
FyldUKategorier();
App.splashScreen.LoadComplete();
}
PS: Если вы знаете какое-либо лучшее решение, которое бы делало то же самое, что я пытаюсь сделать здесь, не стесняйтесь дать ссылку для него.
[Изменить] Я изменился, поэтому я больше не использую app.xaml, так как я не хочу его при запуске, я переместил код в главное окно, где он будет использоваться.
Теперь он больше не падает, но показывает мое окно только в первый раз, ничего кроме этого просто не показывает ничего.
[Правка-2] Я провел несколько тестов и решил сделать окно намного лучше, и именно тогда я столкнулся с тем, в чем именно заключается проблема. Кажется, что приведенный выше код теперь работает нормально после того, как я переместил его в свой Main вместо того, чтобы заставить его работать в App.xaml. Я удалил
public void LoadStart()
{
Dispatcher.Invoke((Action)delegate()
{
//this.UpdateMessageTextBox.Text = message;
});
}
также из Loading.xaml, так как у меня нет ничего, чтобы использовать, если для. В экзамене, за которым я следовал, его использовали для обновления ярлыка на самой странице.
Кажется, проблема в установленных мной пакетах, которые должны были показать мне анимированный GIF.
<Image gif:ImageBehavior.RepeatBehavior="Forever" gif:ImageBehavior.AnimatedSource="/img/Animated_ARKA_Loading.gif" />
Новая проблема все тот же проект
Итак, следующая проблема в этом, когда я показываю экран загрузки, он работает при первом запуске звука, когда окно пусто.
Решение проблемы с загрузкой до точки, которую я хотел, находится в приведенном ниже решении, и произошел сбой, потому что я попытался ввести закрытый поток. Я думал, что смогу начать с метода, поэтому решил удалить его.
MainWindow
private void AnimatedLoading()
{
// ManualResetEvent acts as a block. It waits for a signal to be set.
ResetSplashCreated = new ManualResetEvent(false);
// Create a new thread for the splash screen to run on
SplashThread = new Thread(ShowSplash);
SplashThread.SetApartmentState(ApartmentState.STA);
SplashThread.IsBackground = true;
SplashThread.Name = "Splash Screen";
SplashThread.Start();
// Wait for the blocker to be signaled before continuing. This is essentially the same as: while(ResetSplashCreated.NotSet) {}
ResetSplashCreated.WaitOne();
FyldUKategorier();
splashScreen.LoadComplete();
SplashThread.Abort();
}
private void ShowSplash()
{
// Create the window
Loading loading = new Loading();
splashScreen = loading;
// Show it
loading.Show();
// Now that the window is created, allow the rest of the startup to run
ResetSplashCreated.Set();
System.Windows.Threading.Dispatcher.Run();
}
Loading.xaml
public Loading()
{
InitializeComponent();
}
public void LoadComplete()
{
Dispatcher.InvokeShutdown();
}
}
public interface ISplashScreen
{
void LoadComplete();
}