10

WPF UserControl では、WebService を呼び出す必要があります。別のスレッドでこの呼び出しを行っていますが、呼び出しに時間がかかる可能性があることをユーザーに通知したいと思います。

WebMethod はオブジェクトのコレクションを返し、それを UC の ListBox にバインドします。これまでのところ、とても良いです... この部分は本当にうまくいきます。ただし、通話中に進行状況バー (または任意の種類のアニメーション...) を表示したいと考えています。このアニメーションは、ListBox コントロールの上に中央に配置されます。

Adorner を試してみましたが、部分的に機能します。ただし、保護されたオーバーライド void OnRender(DrawingContext drawingContext) ですべてのコントロールを描画する必要があります...数秒間コントロールを追加したいだけです...

どうすればこれを達成できるか考えている人はいますか?

ありがとう!

4

2 に答える 2

10

アドナーと一緒に行かないでください。私がしているのは、画面の同じ領域を占める 2 つの別個のコンテナー コントロール (通常はグリッド) です。1 つは「進行状況」コントロールで、もう 1 つは「コンテンツ」コントロールです。デフォルトで、プログレス コントロールの可視性を Collapsed に設定し、コンテンツ コントロールの可視性を Visible に設定します。

そのように設定した場合、Web サービスへの非同期呼び出しを開始すると、進行状況コントロールが表示され、コンテンツ コントロールが折りたたまれます。Web サービスが終了したら、Dispatcher.BeginInvoke を使用して UI を更新し、その時点でプログレス コントロールを折りたたみ状態に戻し、コンテンツ コントロールを表示状態に戻します。

私は通常、進捗管理を不確定にします。以下に例を示します。これには、進行状況バーを持つ ProgressGrid という別の UserControl があります。

    <Grid x:Name="layoutRoot">
        <Grid x:Name="contentGrid" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Visible">
             <!-- snip -->
        </Grid>

        <controls:ProgressGrid x:Name="progressGrid" Text="Signing in, please wait..." Visibility="Collapsed"/>
    </Grid>

そして、コードビハインドでは、次のような単純なものだけです:

    private void SignInCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        contentGrid.Visibility = Visibility.Collapsed;
        progressGrid.Visibility = Visibility.Visible;
    }
于 2008-12-01T00:59:17.343 に答える
1

高さがゼロのキャンバスで使用できるトリックがあり、うまくいくかもしれません。Chris Anderson の WPF ブックでは、これとそれが機能する理由について詳しく説明されていますが、次のようになります。

  • スタックパネルを作成する
  • Height="0" で z-index が高い Canvas をスタック パネルに追加します。
  • ユーザー コントロールをスタック パネルに追加します。

プログレス バーを表示する場合は、高さゼロのキャンバスに追加します。これにより、ユーザー コントロールの上に配置できます。キャンバスを使用すると、その境界を超えることができます。プログレス バーを中央に配置するには、ユーザー コントロールのサイズを確認し、それに応じてキャンバス上のプログレス バーの位置を設定する必要があります。完了したら、キャンバスからプログレス バーを削除します。

TextBox を使用した簡単な例を次に示します。完璧ではありませんが、アイデアを示しています。ボタンをクリックすると、InkCanvas の上に TextBox が表示されます

<DockPanel LastChildFill="True">
    <Button DockPanel.Dock="Top" Name="showButton" Click="showProgress">show</Button>
    <StackPanel DockPanel.Dock="Bottom">
        <Canvas Name="zeroHeight" Height="0"/>
        <InkCanvas Name="inky">
        </InkCanvas>
    </StackPanel>
</DockPanel>


private void showProgress(object sender, RoutedEventArgs e)
{
    TextBox box = new TextBox();
    box.Text = "on top";
    StackPanel.SetZIndex(zeroHeight, 8);
    zeroHeight.Children.Add(box);
    box.Width = 30;
    box.Height = 30;
    Canvas.SetLeft(box, 10);
    Canvas.SetTop(box, 10);
    Canvas.SetZIndex(box, 10);
}
于 2008-12-01T00:59:38.933 に答える