How can I avoid flicker in a WPF fullscreen app?

后端 未结 8 781
春和景丽
春和景丽 2020-12-31 11:41

I have a WPF application that is a fullscreen kiosk app. It\'s actually a pretty complicated app at this point, but here\'s some code that shows the basic idea. Essentiall

相关标签:
8条回答
  • 2020-12-31 12:15

    As answered earlier using Frames/Tab Controls avoid flicker during transitions

    If you don't want to change your application and want to remove that flicker (flashing of desktop in between) on Windows7 or WindowsVista you can optimise your windows 'Visual Effects' setting to be 'Adjust for best performance'

    0 讨论(0)
  • 2020-12-31 12:16

    The underlying cause of the flicker is that whenever you .Hide() a window its PresentationSource is disconnected, causing Unloaded events to be fired on everything and everything cached in the MILCore layer of WPF to be discarded. Then when you .Show() it again later, everything is rebuilt.

    To prevent flicker, make sure you keep your UI connected to a PresentationSource at all times. This can be done in several ways:

    Single window with a disguised TabControl

    Use a single window containing a TabControl styled so you can't see the tabs. Switch tabs in code when you would normally show or hide windows. You can simply search-and-replace "Window" in your existing code with "Page", then replace "Show()" calls to your custom "Show()" which does the following:

    1. Check for previously created TabItem for this Page (using a Dictionary)
    2. If no TabItem found, wrap the Page inside a new TabItem and add it to the TabControl
    3. Switch the TabControl to the new TabItem

    The ContentTemplate you would use for your TabControl is extremely simple:

    <ContentTemplate TargetType="TabControl">
      <ContentPresenter x:Name="PART_SelectedContentHost"
                        ContentSource="SelectedContent" />
    </ContentTemplate>
    

    Using a Frame with Navigation

    Using Frame with Navigation is a very good solution for a kiosk because it implements a lot of the page switching and other functionality. However it may be more work to update an existing application this way than to use a TabControl. In either case you need to convert from Window to Page, but with Frame you also need to deal with navigation.

    Multiple windows with opacity

    You can make a window almost completely invisible using a low opacity and yet WPF will still keep the visual tree around. This would be a trivial change: Just replace all calls to Window.Show() and Window.Hide() with calls to "MyHide()" and "MyShow()" which updates the opacity. Note that you can improve this further by having these routines trigger animations of very short duration (eg 0.2 second) that animate the opacity. Since both animations will be set at the same time the animation will proceed smoothly and it will be a neat effect.

    0 讨论(0)
  • 2020-12-31 12:17

    Agreed with the comments about using the built-in navigation functionality, but if you're locked in to your design at this point, perhaps consider animating the opacity of your windows? A short 100 or 200 ms animation of Opacity from 1 -> 0 for the outgoing window and 0 -> 1 for the incoming window might resolve the issue. Handle the actual cleanup of the outgoing window in the Completed event on the storyboard.

    0 讨论(0)
  • 2020-12-31 12:18

    Here is an easy alternative that works for me in my kiosk-like application with a black background, inspired from above answers. Here I have a "LanguageWindow" that can be opened from anywhere in the application to change the current language.

    In LanguageWindow.xaml (check the WindowState=Minimized):

    <Window x:Class="LanguageWindow"
        ...
        Title="LanguageWindow" Height="1024" Width="1280" WindowStyle="None" WindowState="Minimized" Background="Black">
    

    In LanguageWindow.xaml.vb:

    Private Sub LanguageWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        Me.WindowState = WindowState.Maximized
    End Sub
    

    Voilà!

    (done with Visual Studio 2015, .NET Framework 4.6, WPF, VB.net)

    0 讨论(0)
  • 2020-12-31 12:20

    WPF has built in navigation functionality.

    Just look at the Frame and the Page classes which you can easily design using VS or Blend.

    0 讨论(0)
  • 2020-12-31 12:22

    If you have any initialization in the constructor that takes a long time that could cause a delay and flicker. You could try using an asynchronous method or put that initialization on a background thread so that it does not block the showing of the window.

    An example of something which would cause a delay would be a database query or a request for data over a network.

    A quick experiment would be to disable parts of the constructor in a slow Window to find out what is causing delay in showing the Window.

    0 讨论(0)
提交回复
热议问题