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/
Related
i will first explain the UI of my WPF App.
I have created a window which contains many buttons which is always visible to the user(lets call it main window), each button will open a new window relevant to the task. what i want done is that whenever a button is clicked, the main window should be hidden(visibility : collapsed) and the new window should be shown. This second window will also contain a button which will hide the second window and show back the main window.
also the second window which will be opening will have different dimensions as per the command associated with it so i will be having different windows for eaach
TLDR i want to be able to switch between multiple windows such that only one window is visible at one time, how do i manage the switching between multiple windows ??
Note : I can show the second window from main window but what about showing main from the second window....can't get it....or if anyone can show me a different approach to implement this : other than multiple windows
Also, this is an extension to the UI, i want to show the buttons in this crystalised sort of look like on this page : http://postimage.org/image/4yibiulsh/
can anyone direct me to a proper implementation, i have been through many sites and also tried to create these through blend but i just am not a UI Person....pls need help on this
Thanks in advance.
I would create a "Window manager" which will subscribe to the changes of opening/closing.
In this case you don't have to overload Window classes.
Example (worked for me).
public class WindowsManager
{
static readonly List<Window> Windows=new List<Window>();
public static T CreateWindow<T>(T window) where T:Window
{
Windows.Add(window);
window.Closed += WindowClosed;
window.IsVisibleChanged += WindowIsVisibleChanged;
return window;
}
static void WindowIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var mainWindow = Application.Current.Windows.OfType<MainWindow>().Single();
mainWindow.Visibility = Equals(e.NewValue, true) ? Visibility.Hidden : Visibility.Visible;
}
static void WindowClosed(object sender, System.EventArgs e)
{
var window = (Window) sender;
window.Closed -= WindowClosed;
window.IsVisibleChanged -= WindowIsVisibleChanged;
Windows.Remove(window);
}
}
How to use:
private void button1_Click(object sender, RoutedEventArgs e)
{
WindowsManager.CreateWindow(new Child1()).Show();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
WindowsManager.CreateWindow(new Child2()).Show();
}
So, when the child window will close, WindowsManager will be notified about this and will update visibility for the main window
UPD1.
added line to unscubscribe from VisibleChanged
You can use several approaches for that.
To easy switch back to main Window: inject a reference of your MainWindow to your SecondWindow (or any other Window you want to display) and in the Closing Event of that Window you set the Visibility of the MainWindow back to Visible.
Have you also considered keeping everything in the same Window but having different Panels that you set Visible and Invisible? That could have the same effect but it's less complicated...
Hope that helps...
I have a Silverlight application which has a RadHtmlPlaceholder which points to ssrs to display reports like so:
<telerik:RadHtmlPlaceholder SourceUrl="http://serverName/ReportServer/Pages/ReportViewer.aspx?/Northwind/Employees&rs:Command=render" />
This works fine but when I have a report that allows you to drill down to display a child report, there is no way of getting back to the parent report without having to load the whole lot again. There doesn't seem to be an option to turn on the navigate back button toolbar option and I've seen other ways of implementing a back button by using javascript to set the window location back one in the history, but obviously this won't work in a Silverlight application. Is there anyway to implement a navigate back button?
Take a look at this thread over in the Telerik forums: http://www.telerik.com/community/forums/silverlight/htmlplaceholder/html-place-holder-back-forward-refresh.aspx
Basically you need to get a handle on the IFrame from the presenter and inject some JavaScript. The history object also has a length property you can use to evaluate if your buttons should be enabled.
public MainPage()
{
InitializeComponent();
// Get the IFrame from the HtmlPresenter
HtmlElement iframe = (HtmlElement)htmlPlaceholder.HtmlPresenter.Children[0];
// Set an ID to the IFrame so that can be used later when calling the javascript
iframe.SetAttribute("id", "myIFrame");
}
private void Refresh_Click(object sender, RoutedEventArgs e)
{
// Code to be executed
string code = "document.getElementById('myIFrame').contentWindow.location.reload(true);";
HtmlPage.Window.Eval(code);
}
private void Back_Click(object sender, RoutedEventArgs e)
{
// Code to be executed
string code = "document.getElementById('myIFrame').contentWindow.history.back();";
HtmlPage.Window.Eval(code);
}
private void Forward_Click(object sender, RoutedEventArgs e)
{
// Code to be executed
string code = "document.getElementById('myIFrame').contentWindow.history.forward();";
HtmlPage.Window.Eval(code);
}
}
I have a silverlight application that uses WCF, and I would like to make a WCF call to load some data before the usercontrol is loaded so that I could use the data with an autocompletebox. Any suggestions as to how to accomplish this?
Not sure if your user interface will be suitable to use a loading indicator or a progress bar. If you can use loading indicator, then it might be a good option to display the busy / loading indicator while the async call is in progress. That would disable the user from clicking on the dropdown or any other control while the data is being retrieved from the WCF service.
You can do the async call in the Application_Startup() method of your App.xaml.cs file, and set RootVisual in your async callback instead of in Application_Startup().
All WCF service calls in Silverlight are asynchronous. I've learned to use Lambdas and a very useful class called Action (which is a wrapper for an event and a delegate).
Using the application startup as RobSiklos suggested would work great for getting it before showing the control. This shows the code that could also work inside of the userControl loaded event, incorporating a loading overlay (you could use a border with centered text that goes over the whole app or a Silverlight toolkit control). This approach will give more immediate feedback to the user, especially if your data service call will take a longer time.
public MyUserControl : UserControl
{
public MyUserControl()
{
this.Loaded += new RoutedEventHandler(View_Loaded);
}
void View_Loaded(object sender, RoutedEventArgs e)
{
// start showing loading overlay
MyService service = new Service(...);
service.GetDataCompleted += (o, args) =>
{
var data = args.Results;
// hide loading overlay
}
}
}
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
I am able to load an rtf document in a RichTextBox, but the links that the document contains to some websites are not working.
Anyone have any idea why? Some solution to make the links work?
Best regards,
Paulo Azevedo
WPF by default doesn't understand where you want the links to be displayed, so what's happening is that the Hyperlink class is firing an event, RequestNavigate, and expecting you, the application designer, to cause the actual navigation to occur.
I assume you just want to launch the system configured web browser, so here's all you need to do:
Hook the Hyperlink::RequestNavigate routed event
Call Process.Start with the URL you receive to have the OS launch the browser.
That might look a little something like this:
public class MyWindow : Window
{
public MyWindow()
{
this.InitializeComponent();
this.myRichTextBox.AddHandler(Hyperlink.RequestNavigate, MyWidow.HandleRequestNavigate);
}
private static void HandleRequestNavigate(object sender, RequestNavigateEventArgs args)
{
Process.Start(args.Uri.ToString());
}
}