Adding a minimum display time for Silverlight splash screen - silverlight

When hosting a silverlight application on a webpage it is possible to use the splashscreensource parameter to specify a simple Silverlight 1.0 (xaml+javascript) control to be displayed while the real xap file is downloaded, and which can receive notification of the downloads progress through onSourceDownloadProgressChanged. If the xap file is in cache, the splash screen is not shown (and if the download only takes 1 second, the splash screen will only be shown for 1 second).
I know this is not best practice in general, but I am looking for a way to specify a minimum display time for the splash screen - even if the xap cached or the download is fast, the splash screen would remain up for at least, let's say, 5 seconds (for example to show a required legal disclaimer, corporate identity mark or other bug).
I do want to do it in the splash screen exclusively (rather then in the main xap) as I want it to be clean and uninterupted (for example a sound bug) and shown to the user as soon as they open the page, rather then after the download (which could take anywhere from 1 to 20+ seconds).
I'd prefer not to accomplish this with preloading - replacing the splash screen with a full Silverlight xap application (with it's own loading screen), which then programmably loads and displays the full xap after a minimum wait time.

Its a little known fact that the splash screen remains in place beyond the time that XAP takes to load. It doesn't get replaced until the application RootVisual loads. Hence if you don't assign the RootVisual in the application Startup event the splash screen displays forever.
Hence you can delay the display of the splash for a few seconds using code like this:-
private void Application_Startup(object sender, StartupEventArgs e)
{
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(10);
EventHandler eh = null;
eh = (s, args) =>
{
timer.Stop();
this.RootVisual = new Test();
timer.Tick -= eh;
};
timer.Tick += eh;
timer.Start();
}
This can be simplified with the Reactive framework:-
private void Application_Startup(object sender, StartupEventArgs e)
{
Observable.Timer(TimeSpan.FromSeconds(10), Scheduler.Dispatcher)
.Subscribe((l) =>
{
this.RootVisual = new Test();
});
}
However the Reactive framework adds at least 66KB to the size of your Xap so only use it you are already using the Reactive stuff for other things.

Note that if you were only interested in extending the display time of the splash screen during development then it is very simple to add a Fiddler rule which delays the response off the Xap file.
This is an example of a rule that would have this effect. See Pedro Forte's post for details on how to apply the rule - it is really very easy!
if (oSession.uriContains("Midwinter.ReasonableBasis.Client.xap")){
oSession["ui-color"]="orange";
oSession["ui-bold"]="true";
//Delay received data by X ms per KB downloaded.
oSession["response-trickle-delay"] = "10";
}

Related

Force WinForm Application on top Windows 10 Tablet Mode

Is there any way to force a simple winforms application to run on top the tablet mode main screen ?
It can be Vb script or anything, the idea is to show a count down application on top the main screen to announce the upcoming "force shutdown" of that tablet.
screnshot
Whoever face the same problem, there is a "hack" I was reading about.
When on tablet mode, your application will be start as "minimized" in the taskbar, therefore you will not be able to see it, just a "Home screen".
What worked for me was adding to my Form_Load event the SendKey Function, with alt + tab.
That, mixing with #EpicKip answer just above, will always send the app (even when on start screen of "Tablet Mode" and the app on "Minimized").
private void form1_Load(object sender, EventArgs e)
{
//SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
Thread.Sleep(1000);
SendKeys.SendWait("%{TAB}");
}

Clearing previously loaded images in WinForm from resources

Purpose of my WinForm application is to load and display for a short while randomly selected picture from specific folder. I'm doing this using a PictureBox like so (this line gets adjusted by random number generator to generate different number file name):
pictureBox1.Image = Image.FromFile(#"C:\pics\1.png");
After a while it loads different image file, but looking at the Diagnostic View, I see that the Process Memory is rising by approx. 1MB with every image loaded. After about 100 pictures, the size rises by 100MB, even though the pictures were replaced. One of the timers that controls display duration includes some methods I found here to try and flush the image from resources:
private void displayDuration(object sender, EventArgs e)
{
pictureBox1.Visible = false;
pictureBox1.Image = null;
pictureBox1.Invalidate();
timer2.Enabled = false;
}
but to no avail. Memory keeps increasing, but the Tick function works since setting visibility to false works just fine.
How do I properly flush this image from memory once I don't need it anymore?
I'm trying not to include ImageList, but if you think it could resolve this memory issue, I could add it in.
Mr. Reza Aghaei was correct, Dispose() does the trick, I just used it wrong:
pictureBox1.Dispose();
which just ruined the pictureBox. Disposing the image in pictureBox is the correct way:
pictureBox1.Image.Dispose();
I shouldn't have given up on that method so early. Thank you very much.

Changing MediaElement source without Flicker

I have a simple video player that plays a series of videos using the WPF MediaElement. The videos together form one continuous film that move around a still image. At the end of each video the movement freezes on the final frame of the currently playing video. When I press a button the next video plays, which continues the movement around the still image. It's an application I'm going to use to give a speech. Effectively I've got a series of videos for which the last frame of each video is the same as the first frame of the next video.
I'm using a WPF MediaElement and changing the Source property when the user clicks on the mouse.
The problem that I have is that, when I change the Source property, the MediaElement becomes transparent while the next video is loaded. This means there is a flicker between videos. Is there any way of preventing this flicker? What other strategies could I use?
Here's some code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.x_MediaElement.MouseLeftButtonDown += x_MediaElement_MouseLeftButtonDown;
this.MouseLeftButtonDown += MainWindow_MouseLeftButtonDown;
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
}
void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MoveNext();
}
private void MoveNext()
{
_sourceIndex++;
if (_sourceIndex >= _sources.Length)
_sourceIndex = 0;
Debug.WriteLine(string.Format("Playing {0}", _sources[_sourceIndex]));
this.x_MediaElement.Source = new Uri(_sources[_sourceIndex]);
this.x_MediaElement.Play();
}
private int _sourceIndex = -1;
private string[] _sources = new string[] {
//SOURCE GO HERE
};
void x_MediaElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MoveNext();
e.Handled = true;
}
}
I am gonna be honest with you. MediaElement has more bugs than you can count with fingers. Starting from that the mediaElement blows up after playing 20 videos(no more MediaEnded event, it will crash or something like that). And ofcourse the performance. Its not synchronized with vertical sync. So the video might actually seem laggy.
I advise you to look into DirectShow technology(essentially what WPF is based on, but you can switch renderer which will avoid lag). COnsidering that you will not be developing any professional application, I guess MediaElement will be fine.
However, MediaElement is the simplest option, and if it works for you, then keep working with it. As for your problem, I think there are few possible solutions:
Have two MediaElements and switch between them. If one video ends, start another vid in another MediaElement, as long as you play first frame on second mediaElement, hide the first mediaElement, and vice versa. You can poll for position, and maybe MediaStarted event. This way the flicker will be almost impossible to notice.
If you want fluent video playing without ANY flicker at all, there is GMFPlay. You can check it out. Though it's not MediaElement. But it can play videos simultaneously without any flicker.
Take screenshot of the last frame(you can take screenshots with WPF) and show it as Image while MediaElement is secretly loading.

Positioning of Windows Form Application

How do I code the start location of my winform app such that it always starts in the bottom right hand corner of the screen. As using x and y coordinate only affects one particular screen resolution, on a smaller or larger screen the winform would not appear in the desired location.
Thanks!
You have to do this in the OnLoad() method/event, one of the few real reasons to use it. The form's actual size won't be the designed size because the user might have changed preferences like the window caption height or the form might be rescaled due to a different video DPI setting. This is all sorted out when OnLoad() starts running.
Make it look like this:
protected override void OnLoad(EventArgs e) {
var scr = Screen.FromPoint(this.Location);
this.Left = scr.WorkingArea.Right - this.Width;
this.Top = scr.WorkingArea.Bottom - this.Height;
base.OnLoad(e);
}
Check this on MSDN:
Setting the Screen Location of Windows Forms
Regards

Double buffer for Silverlight game

I start learning Silverlight and would like to create some simple game.
I am using CompositionTarget.Rendering event for my animation
But animation is not smooth, I developed games before and I used double buffer to avoid such problems, but I can't find if it possible with Silverlight.
Does anybody know how to create smooth animation with CompositionTarget.Rendering event.
Thanks,
.NET Developer.
Are you assuming that the Rendering event fires at a constant rate? It's not guaranteed to. On my machine it usually fires 60 times per second, but sometimes it's a bit faster and sometimes noticeably slower. It seems to skip a frame on occasion, which could cause your animation not to be smooth.
However, the event gives you the information to determine exactly how long it's been since the last frame (though you have to know how to get it), and you can code your animation to take this into account. Move farther if it's been a longer amount of time since the last frame, etc.
You need to take the EventArgs that's passed to your event handler, cast it to RenderingEventArgs, and then read its RenderingTime property. Calculate the delta in RenderingTime since your last event; that tells you how long it's been since your last frame was shown, and you can use that to pace your animations.
CompositionTarget.Rendering += CompositionTarget_Rendering;
...
private static TimeSpan? _lastRenderTime;
private void CompositionTarget_Rendering(object sender, EventArgs e) {
var args = (RenderingEventArgs) e;
var elapsed = _lastRenderTime.HasValue ?
args.RenderingTime - _lastRenderTime.Value :
TimeSpan.Empty;
_lastRenderTime = args.RenderingTime;
// "elapsed" tells you how long since the last frame.
// Now you can update your animation accordingly. For example,
var left = Canvas.GetLeft(_myControl);
left += elapsed.TotalSeconds * 100;
Canvas.SetLeft(_myControl, left);
}
I've heard that, at least in WPF, RenderTime doesn't tell you the current time, but rather what time it will be when the frame is shown on the screen. I haven't seen that substantiated from official sources, and even if it's true, I don't know if it's true for Silverlight as well. But whatever the case, it will give you the best possible information for writing your animation.
How much processing do you perform in Rendering event? As one option you can render part of your scene into WriteableBitmap and only use rendering event to swap bitmaps.

Resources