如果这是重复的话,我道歉,但我无法找到类似情况的问题。如果这是重复,请提供链接。
我想在我的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以“强制”显示叠加层。但我无法让它发挥作用......
你能告诉我如何完成这项任务吗?更重要的是;提供解释,因为我没有得到这个。
事先, 谢谢。
祝你好运, CasperKorshøj
答案 0 :(得分:0)
您无法在后台线程中操纵UI控件。如果您使用主UI线程来创建TabItem
,那么您也无法拥有一个忙碌的&#39;或者&#39;正在加载&#39;指示符...如果您在长时间运行的过程中使用备用线程,这将仅工作。这是因为你的忙碌&#39;只有在长时间运行的进程在同一个UI线程上运行时,指示符才会更新。