11

フルスクリーンのキオスク アプリである WPF アプリケーションがあります。この時点では実際にはかなり複雑なアプリですが、基本的な考え方を示すコードをいくつか示します。基本的に、ユーザーがある画面から次の画面に移動するたびに、新しいウィンドウが表示されるときに深刻なちらつきが発生します。深刻な場合、新しい画面が表示される前にデスクトップが数秒間表示されます。このサンプル コードは非常に単純であるため、このようなことはありませんが、さらにいくつかのボタンとスタイルを追加すると、それが表示されます。

アプリ.xaml.cs:

public partial class App : Application {
    Manager mManager;
    public App() {
        mManager = new Manager();
        Window1 screen1 = new Window1(mManager);
        mManager.Screen1 = screen1;
        try {
            this.Run(screen1);
        } catch (Exception e) {
            System.Console.WriteLine(e.ToString());                
        } finally {
            Application.Current.Shutdown();
        }
    }
}

Window1.xaml.cs:

public partial class Window1 : Window {
    Manager Manager{get; set;}
    public Window1(Manager inManager) {
        InitializeComponent();
        Manager = inManager;
    }

    private void OnChangeScreen(object sender, RoutedEventArgs e) {
        Manager.OpenScreen2();
    }
}

Window2.xaml.cs:

public partial class Window2 : Window {
    Manager Manager{get; set;}
    public Window2(Manager inManager) {
        InitializeComponent();
        Manager = inManager;
    }

    private void OnChangeScreen(object sender, RoutedEventArgs e) {
        Manager.OpenScreen1();
    }
}

Manager.cs:

public class Manager {
    public Window1 Screen1{ get; set;}
    public Window2 Screen2{ get; set;}

    public Manager(){
        Screen1 = new Window1(this);
    }

    public void OpenScreen2() {
        Screen2 = new Window2(this);
        Screen2.Show();
        if (Screen1 != null) {
            Screen1.Hide();
        }
    }

    public void OpenScreen1() {
        Screen1 = new Window1(this);
        Screen1.Show();
        if (Screen2 != null) {
            Screen2.Hide();
        }
    }
}

Window1.xaml (本質的には window2.xaml によって模倣されます):

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" 
        WindowStyle="None"
        WindowState="Maximized"
        Width="1280"
        Height="1024"
        FontFamily="Global User Interface"
        ResizeMode="NoResize">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Button Name="ChangeScreenButton" Click="OnChangeScreen" Grid.Row="2" Grid.Column="2" Content="Toggle Screen 2"></Button>
    </Grid>
</Window>

2 つのウィンドウの表示をインターリーブしても (つまり、ウィンドウ 2 を削除する前にウィンドウ 1 を表示するなど)、ちらつきの動作は変わりません。この単純なアプリでは、表示されていない他の画面を非表示にするだけで済みますが、より複雑なアプリでは、状態情報が多すぎて画面情報を適切かつ簡単に管理できません。

ちらつきを回避するための魔法のコードワードやテクニックはありますか? この時点で、非表示と表示をサポートするために UI 全体を書き直さなければならないのではないかと心配していますが、それは私の時間枠では実現不可能です。

編集:いくつかのダイアログで非表示/表示を試しましたが、問題ではないようです。メインのキオスクアプリがスタイルヘビーだからでしょうか?

4

8 に答える 8

15

PresentationSourceちらつきの根本的な原因は、.Hide() ウィンドウが切断されるたびにUnloaded、すべてのイベントが発生しMILCore、WPF のレイヤーにキャッシュされたすべてが破棄されることです。その後、.Show()後でもう一度実行すると、すべてが再構築されます。

ちらつきを防ぐために、UI が常に PresentationSource に接続されていることを確認してください。これは、いくつかの方法で行うことができます。

偽装された TabControl を含む単一のウィンドウ

TabControlタブが見えないように、スタイルを含む単一のウィンドウを使用します。通常はウィンドウを表示または非表示にするときに、コードでタブを切り替えます。既存のコードの「ウィンドウ」を検索して「ページ」に置き換えるだけで、「Show()」呼び出しをカスタムの「Show()」に置き換えることができます。これにより、次のことが行われます。

  1. このページの以前に作成された TabItem を確認します (辞書を使用)
  2. TabItem が見つからない場合は、Page を新しい TabItem 内にラップし、それを TabControl に追加します。
  3. TabControl を新しい TabItem に切り替えます

TabControl に使用する ContentTemplate は非常に単純です。

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

ナビゲーションでのフレームの使用

ナビゲーションと一緒に使用Frameすることは、多くのページ切り替えやその他の機能を実装するため、キオスクにとって非常に優れたソリューションです。ただし、この方法で既存のアプリケーションを更新する方が、TabControl を使用するよりも手間がかかる場合があります。どちらの場合も から に変換する必要がありWindowますPageが、Frame ではナビゲーションも処理する必要があります。

不透明な複数のウィンドウ

低い不透明度を使用してウィンドウをほぼ完全に非表示にすることができますが、WPF はビジュアル ツリーを維持します。これは簡単な変更です。不透明度を更新する "MyHide()" および "MyShow()" へのすべての呼び出しWindow.Show()と呼び出しを置き換えるだけです。Window.Hide()これらのルーチンで、不透明度をアニメーション化する非常に短い時間 (0.2 秒など) のアニメーションをトリガーすることで、これをさらに改善できることに注意してください。両方のアニメーションが同時に設定されるため、アニメーションがスムーズに進行し、きちんとした効果が得られます。

于 2010-03-02T16:40:45.167 に答える
2

キオスクで同じアプリケーションに複数のウィンドウを使用している理由が気になります。すべてのコントロールを同じ「ウィンドウ」に簡単に配置し、パネルの可視性を変更して異なる「画面」を表示することができます。これにより、デスクトップが表示されなくなり、フェードトランジションやスライドアニメーションなどのきちんとしたことができるようになります.

于 2010-03-02T15:45:05.160 に答える
2

WPF にはナビゲーション機能が組み込まれています。

VS または Blend を使用して簡単に設計できるFrameクラスと Page クラスを見てください。

于 2010-03-02T15:49:13.513 に答える
0

コンストラクターで初期化に時間がかかる場合、遅延やちらつきが発生する可能性があります。ウィンドウの表示をブロックしないように、非同期メソッドを使用するか、その初期化をバックグラウンド スレッドに置くことができます。

遅延の原因となるものの例としては、データベース クエリやネットワークを介したデータの要求があります。

簡単な実験として、遅い Window でコンストラクターの一部を無効にして、Window の表示の遅延の原因を突き止めます。

于 2010-03-02T16:37:46.420 に答える
0

組み込みのナビゲーション機能の使用に関するコメントには同意しますが、この時点でデザインに縛られている場合は、ウィンドウの不透明度をアニメーション化することを検討してください。不透明度の短い 100 または 200 ミリ秒のアニメーションで、発信ウィンドウの場合は 1 -> 0、着信ウィンドウの場合は 0 -> 1 で問題が解決する場合があります。ストーリーボードの Completed イベントで、発信ウィンドウの実際のクリーンアップを処理します。

于 2010-03-02T15:56:02.280 に答える
0

WPF が DirectX とグラフィック プロセッサを使用して画面要素の処理をオフロードする方法を見て、コンピュータの DirectX とドライバは最新ですか?

コーリー

于 2010-03-02T15:57:35.057 に答える
0

上記の回答から着想を得た、黒い背景を持つキオスクのようなアプリケーションで私にとってうまくいく簡単な代替手段を次に示します。ここに、アプリケーションのどこからでも開いて現在の言語を変更できる「LanguageWindow」があります。

LanguageWindow.xaml で (WindowState=Minimized を確認します):

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

LanguageWindow.xaml.vb:

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

ほら!

(Visual Studio 2015、.NET Framework 4.6、WPF、VB.net で実行)

于 2016-01-31T22:45:05.880 に答える
0

フレーム/タブコントロールを使用して以前に回答したように、遷移中のちらつきを回避します

アプリケーションを変更せず、Windows7 または WindowsVista でそのちらつき (間のデスクトップの点滅) を削除したい場合は、ウィンドウの「視覚効果」設定を「最適なパフォーマンスに調整する」に最適化できます。

于 2011-06-17T15:46:45.063 に答える