2

如果这是重复的,我深表歉意,但我无法找到类似情况的问题。如果这是重复的,请提供链接。

当我动态创建很多选项卡时,我想在我的 WPF 应用程序中显示“正在加载...”覆盖。覆盖可见性绑定到一个名为“ShowIsLoadingOverlay”的属性。但是,从不显示叠加层。

由于选项卡是视觉元素,我无法将创建移动到 BackgroundWorker。

我创建了一个小原型试图解释这种情况。这是xml:

<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 更改为“强制”显示覆盖。但我就是不能让它工作......

你能告诉我如何完成这个任务吗?更重要的是;提供解释,因为我不明白。

提前谢谢你。

最好的问候, Casper Korshøj

4

1 回答 1

0

您不能在后台线程中操作 UI 控件。如果您使用主 UI 线程来创建您TabItem的 s,那么您也不能有一个“忙碌”或“正在加载”指示器......这只有在您为您的长期运行进程使用替代线程时才有效。这是因为如果长时间运行的进程在同一 UI 线程上运行,您的“忙碌”指示器只会在长时间运行的进程完成后更新。

于 2013-09-10T13:44:53.930 回答