How to display a splash screen using Caliburn Micro - wpf

I'm using Caliburn Micro v1.3 with WPF. I would like to display a splash screen while my app loads.
I have overriden OnStartup as below but can't see how to close my splash when the base.OnStartup complete
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
var wm = new WindowManager();
var vm = new StatusReporterViewModel("TEST", "information", null);
try
{
wm.ShowWindow(vm);
base.OnStartup(sender, e);
}
finally
{
vm.TryClose();
}
}
Any ideas?
Cheers
Steve

If you want to use the default WPF splash mechanism then it requires no code.
Add an image file to your WPF .EXE project and then set the properties on the image to "SplashScreen"

If your Splash Screen is an actual customized Window, you can close the SplashScreen in the OnInitialize() Method of your ShellViewModel (or if you dont have a shell, the first view model that gets activated). To get a reference to the SplashScreen in your Shell either inject it or make it a singleton

Related

Dynamically Change Content by clicking RibbonPane using Prism

I'm using Microsoft Ribbon and Prism to develop my application. I have in my main window 2 regions: one for the ribbon and the other to inject a view depending on the button clicked in my ribbon.
That works pretty good, but I would like to have the same functionality if I click a specific ribbon tab.
Has anyone done anything like this using Prism?
As you wanted, here is the code using a Button. This code is in the VM of the Ribbon...when the button is clicked the event goes to OnShowConfiguration. This method load a new View in my GeneralContentRegion and also a new RibbonTab.
private void OnShowConfiguration()
{
loadView(PrismViewsNames.GeneralContentMainView, PrismRegionsNames.ContentRegion);
loadView(PrismViewsNames.GeneralRibbonTab, PrismRegionsNames.RibbonMenuRegion);
}
private void loadView(string viewToShow, string regionWhereToShow)
{
var regionManager = (RegionManager)ServiceLocator.Current.GetInstance<IRegionManager>();
var uri = new Uri(viewToShow, UriKind.Relative);
regionManager.RequestNavigate(regionWhereToShow, uri);
}
Myabe that helps you, Ayyappan Subramanian ;)

The best approach to show/hide windows indpendently

I am a student and am building a C# WPF application. It has three windows:
Sign in window
Create account window
and Main application window.
I uploaded a figure to show the type of navigation I am trying to implement:
I do not think it is correct to make a window show up/hide inside the close/load event of another window.
Can someone show me the right way to implement this navigation?
Also, is it a good practice to make the three windows private properties of the application class?
The last window has a frame control to support page navigation. Again, is it better to make the three pages private properties of MainWindow application?
I am sorry if this is so obvious or easy to do.
Thanks
I would not have the three windows as properties of the application. I'd instanciate a copy of the sign-in window and use that as my central point of control.
When the user logs in, hide the sign in window, show a new main window and add a hook on the main windows Closed event.
e.g
if (logonSuccess)
{
var mainWindow = new MainWindow();
mainWindow.Closed += ReshowSignupWindow;
}
I'd also have the sign-in window do the same for the create account window. Thus, I'd have the create account window return to the signup window which would either reshow itself or start the main window if an account was created.
e.g.:
// In sign-in window, handle the create window being closed
private void CreateWindowClosedHandler(object sender, EventArgs e)
{
if (accountCreatedOK)
{
ShowMainWindow();
}
else
{
ReshowSignupWindow();
}
}
I'd probably look at having the create account window shown as a dialog window via a call to ShowDialog().
Hope that helps...
Something like this code might do it (untested, I just typed it in visual studio to autoformat the code)
The XAML is for the Login Dialog. The RegistrationDialog should be similar, except for the button and handler for the registration Button.
<Window x:Class="WpfApplication1.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LoginWindow">
<StackPanel>
<Button IsDefault="True" Content="Submit" Click="SubmitButton_Click"/>
<Button IsCancel="True" Content="Cancel" />
<Button Content="CreateAccount" Click="CreateAccountButton_Click"/>
</StackPanel>
</Window>
//Handler of LoginWindow and RegistrationWindow
private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
//Handler of LoginWindow only
private void CreateAccountButton_Click(object sender, RoutedEventArgs e)
{
this.IsCreatingAccount = true;
this.DialogResult = false;
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
bool isCanceled;
while (loginWin.ShowDialog() == false && !isCanceled)
{
if (loginWin.IsAccountCreationRequested)
{
if (registrationWin.ShowDialog())
{
isCanceled = true;
}
else
{
loginWin.IsAccountCreationRequested = false;
}
}
else
{
isCanceled = true;
}
}
if (loginWin.DialogResult) MainWindow.Show();
}
}
I am currently working on a Silverlight Application which is more or less similar to your application. What i feel is your can have 2 xaml controls(one for Login and other for your main application). For create account, you can use a child window which will be called from login control. And use a TabControl in your main application which will hold your other 3 xaml controls(Page1.xaml, Page2.xaml and Page3.xaml). Feel free to ask if you have any issues.
Dont forget to mark my reply as answer if it solves your problem.
I suggest you to follow the pattern. Your logic looks tightly binding with UI(user Interface) and logics.
The best pattern i like is for WPF or Silverlight is MVVM(Model View View Model). There are lot of Examples available in google for MVVM.
Just put a glance in anyone MVVM example you will be clear in developing WPF or Silverlight app.
some links are below,
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
http://www.c-sharpcorner.com/UploadFile/raj1979/simple-mvvm-pattern-in-wpf/
http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute

About Silverlight UserControl

I Have attached a silver light user control (ex: FirstUserControl.xaml) into my silverlight navigation page project. If I wanna run the application, i need to show the added user control as startup page. How can I set the user control as defualt page in silverlight?
Can any one please give me the solution for this?
You can set it in your App.cs Application_Startup method:
private void Application_Startup(object sender, StartupEventArgs e)
{
// Specify the main application UI
this.RootVisual = new FirstUserControl();
}

WPF splash screen until windows ends loading

I have an application that consumes a lot of time when the window loading.
In the Window_load event, I read from the database the state and the name of some controls.
I want to do a splash screen that will ends after the window will fully load.
I have tried with this example http://www.codeproject.com/KB/dialog/wpf_animated_text_splash.aspx but the splash screen closes before the main window is fully loaded and my mainwindow appears in white and is not fully loaded.
I am beginner in wpf, and I don't know how can I have a splash screen which remain on the screen until the main window fully loads.
Please give me an example.
My Splash Screen Code:
public partial class SplashWindow : Window
{
Thread loadingThread;
Storyboard Showboard;
Storyboard Hideboard;
private delegate void ShowDelegate(string txt);
private delegate void HideDelegate();
ShowDelegate showDelegate;
HideDelegate hideDelegate;
public SplashWindow()
{
InitializeComponent();
showDelegate = new ShowDelegate(this.showText);
hideDelegate = new HideDelegate(this.hideText);
Showboard = this.Resources["showStoryBoard"] as Storyboard;
Hideboard = this.Resources["HideStoryBoard"] as Storyboard;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
loadingThread = new Thread(load);
loadingThread.Start();
}
private void load()
{
Thread.Sleep(6000);
this.Dispatcher.Invoke(showDelegate, "first data to loading");
Thread.Sleep(6000);
//load data
this.Dispatcher.Invoke(hideDelegate);
Thread.Sleep(6000);
this.Dispatcher.Invoke(showDelegate, "second data loading");
Thread.Sleep(6000);
//load data
this.Dispatcher.Invoke(hideDelegate);
Thread.Sleep(6000);
this.Dispatcher.Invoke(showDelegate, "last data loading");
Thread.Sleep(6000);
//load data
this.Dispatcher.Invoke(hideDelegate);
//close the window
Thread.Sleep(6000);
this.Dispatcher.Invoke(DispatcherPriority.Normal,(Action)delegate() { Close(); });
}
private void showText(string txt)
{
txtLoading.Text = txt;
BeginStoryboard(Showboard);
}
private void hideText()
{
BeginStoryboard(Hideboard);
}
}
And this splash screen I will call in my MainWindow constructor:
new SplashWindow().ShowDialog();
But my MainWindow Load function will run after the Splash Window will finish to be showed.
Thank you!
If you use the built-in SplashScreen class, you can call Show(false) to specify that you will be responsible for closing the splash screen. You can then use the Close() method to close it.
Note that the SplashScreen class only supports displaying a static image. It does this for very good reasons though - to get the splash screen up in front of your user as soon as possible.
Code would look something like this:
static class Entry
{
static void Main(string[] args)
{
var splashScreen = new SplashScreen("path/to/your/image.png");
splashScreen.Show(false);
InitializeLogging();
InitializeServices();
InitializeUserInterface();
InitializeWhateverElseYouNeed();
splashScreen.Close(TimeSpan.FromSeconds(1));
}
}
Dynamic splash screen (with progress updates etc.)
For the best results, you can use two-phase approach to SplashScreen:
Phase 1. Display static splash screen even before .NET code starts loading.
Static image loads using native code yet before .NET is initialized. Very effective to inform the user as soon as possible. There is a special way to achieve this.
Phase 2. Display custom form once .NET is loaded.
Design your custom form looking identically to your static splash screen when initially displayed. Showing the form will automatically fade-out static splash screen shown in Phase 1 (it is done by WPF) and since then you are free to display loading progress of your application. Hide this form (which can be always-on-top window) when your main window finishes loading its data.
If your splash screen is just an image - add the image to the project and set it's Build Action property to 'SplashScreen'. The framework will handle the rest. (VS2008 sp1 or later).
If you need the splash screen to differ (maybe displaying a version number) this approach wont work. If you want this take a look at the SplashScreen class that gives a little more flexibility.
May be because your data loading is complete but your UI thread have not finished rendering yet.Make sure that your UI is completely rendered before closing the splash.
Have a look the below links.
http://www.codeproject.com/KB/WPF/WPFsplashscreen.aspx
http://www.japf.fr/2009/10/measure-rendering-time-in-a-wpf-application/

Cannot show up WPF application when setting MainWindow manually and composing application (MEF)

I got my hands om MEF for a week now and I am trying to build up a WPF application that loads imported controls from MEF.
I created a WPF application project and removed the default window and application start up URI. Then I handled the application startup event to compose the application:
public partial class App : Application, IPartImportsSatisfiedNotification
{
{...}
private void App_Startup(object sender, StartupEventArgs e)
{
this.Compose();
}
public void Compose()
{
try
{
globalCatalog.Catalogs.Add(new DirectoryCatalog(extensionsDirectoryPath));
CompositionContainer container = new CompositionContainer(globalCatalog);
container.ComposeParts(this);
}
catch (Exception ex)
{
// Do something
}
}
{...}
}
Actually, when debugging and watching objects after imports are satisfied, everything has hierarchically composed fine like I wanted. But when I try to show up the MainWindow of the application an exception is thrown on MainWindow.Show() call:
"Specified element is already the logical child of another element. Disconnect it first."
Though my code in OnImportsSatisfied method seems fine as it is working when not using MEF mecanism:
public void OnImportsSatisfied()
{
Window mainWindow = new Window();
mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();
}
I insist on the fact that this works perfectly when not importing controls with MEF. What is surprising is that this code does not work too:
Window mainWindow = new Window();
//mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();
So I suspect that ComposeParts is doing a bit more than what it says as it is the only member acting on my actual application instance.
Hope someone can help me (Glenn?).
Thanks.
Edit:
I discovered that when I remove the IPartImportsSatisfiedNotification interface from my parts, no exception is thrown and the window shows up. But of course the window is empty as I need this OnImportsSatisfied method to set the DataContext of the window to its associated imported view model.
The sample applications of the WPF Application Framework (WAF) show how to use MEF within a WPF application.
I finally discovered that I was importing my WPF user controls by using the default ImportAttribute constructor, which in fact will make a shared instance of the class if the creation policy is not specified during export. And as many of my controls were implementing the same interface and I was binding them in my views, I was actually trying to add this shared user control instance to different visual elements, which is not permited by WPF (and so the exception).
I marked my imports using the RequiredCreationPolicy set to NonShared and everything got back in order! That was all about learning MEF...

Resources