2

これが重複していたら申し訳ありませんが、同様の状況の質問を見つけることができませんでした. これが重複している場合は、リンクを提供してください。

多くのタブを動的に作成しているときに、WPF アプリケーションで「読み込み中...」オーバーレイを表示したいと考えています。オーバーレイの可視性は、「ShowIsLoadingOverlay」というプロパティにバインドされています。ただし、オーバーレイは表示されません。

タブは視覚要素であるため、作成を BackgroundWorker に移動することはできません。

状況を説明するために小さなプロトタイプを作成しました。これはxamlです:

<Window x:Class="WpfApplication5.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Label HorizontalAlignment="Center" VerticalAlignment="Center" 
               Visibility="{Binding ShowIsLoadingOverlay, Converter={StaticResource BooleanToVisibilityConverter}}" 
               Content="Loading..." />

        <Button Grid.Row="1" Content="Load" Click="Button_Click" />
    </Grid>
</Window>

そして、これは背後にあるコードです:

public partial class MainWindow : Window, INotifyPropertyChanged
{
   private bool m_ShowIsLoadingOverlay;
   public bool ShowIsLoadingOverlay
   {
      get
      {
         return m_ShowIsLoadingOverlay;
      }
      set
      {
         if ( m_ShowIsLoadingOverlay == value )
         {
            return;
         }

         m_ShowIsLoadingOverlay = value;
         NotifyPropertyChanged( "ShowIsLoadingOverlay" );
      }
   }

   public MainWindow()
   {
      InitializeComponent();

      DataContext = this;
   }

   private void Button_Click( object sender, RoutedEventArgs e )
   {
      ShowIsLoadingOverlay = true;

      CreateTabs();

      ShowIsLoadingOverlay = false;
   }

   private void CreateTabs()
   {
      // Simulate long running process to create tabs
      Thread.Sleep( 3000 );
   }

   // Implementation of INotifyPropertyChanged has been left out.
}

問題は、オーバーレイが表示されないことです。ShowIsLoadingOverlay プロパティが変更される前後に、UI が正しく更新されないことに関係があることはわかっています。また、ディスパッチャーを使用していないことも関係していると思います。

プロパティを変更したり、CreateTabs 呼び出しを囲んだりするときに、Dispatcher.Invoke、Dispatcher.BeginInvoke のさまざまな組み合わせを試しました。そして、タブの作成を開始する前に、 DispatcherPriority を変更してオーバーレイを「強制的に」表示しようとしました。しかし、私はそれを機能させることはできません...

このタスクを達成する方法を教えてください。そして更に重要なことに; わからないので説明を。

よろしくお願いします。

敬具、 キャスパー・コルショイ

4

1 に答える 1