如何在Frame导航时显示加载图标?
问题描述:
我有一个框架和一个TreeView的WPF应用程序。 TreeView显示我的应用程序的菜单,并且单击某个项目时,Frame将通过调用Navigate
来显示该菜单项的内容。该调用有时需要几秒钟,导航完成时UI被阻止。如何在Frame导航时显示加载图标?
我有一个控制动画旋转圈(我称之为WaitIcon),我想在框架加载时显示,但它不会出现(即使它确实出现也不会旋转),因为UI线程被阻止加载Frame的内容。我不能在后台线程上调用Navigate
,因为该框架由UI线程拥有。在加载框架时有没有办法显示WaitIcon?可能通过创建拥有WaitIcon的第二个线程?
更新 - 示例代码显示以下问题:
这是主窗口。我只是用一个动画椭圆模拟WaitIcon:
<Window x:Class="FrameLoadingTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Storyboard x:Key="Animation" RepeatBehavior="Forever">
<ColorAnimation From="Red" To="Black" Duration="0:0:2" Storyboard.TargetName="Ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Animation}" />
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Button Click="Button_Click">Load Frame</Button>
<Frame Name="ContentFrame" Grid.Column="1"></Frame>
<Ellipse Name="Ellipse1" Height="100" Width="100" Visibility="Hidden" Fill="Red">
</Ellipse>
</Grid>
</Window>
该按钮的单击事件:
private void Button_Click(object sender, RoutedEventArgs e)
{
Ellipse1.Visibility = Visibility.Visible;
ContentFrame.Source = new Uri("TestPage.xaml", UriKind.Relative);
}
测试页:
<Page x:Class="FrameLoadingTest.TestPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestPage">
<Grid>
<TextBlock>Hello, world</TextBlock>
</Grid>
</Page>
而且我把睡眠在构造函数中模拟长时间运行初始化:
public partial class TestPage : Page
{
public TestPage()
{
InitializeComponent();
Thread.Sleep(3000);
}
}
直到加载页面之后才显示椭圆。
答
WPF动画启动时不能被主线程阻塞。故事板在自己的线程中运行,并且呈现发生在WPF呈现线程中,这与主线程不同。另外,我相信帧加载也是非阻塞的。
所以你的代码还有其他的东西,你为什么不把它发布在这里,以便我们理解。
编辑:我错了故事板。由于资源是在主线程上创建的,因此它在相同的主线程中运行。即使您动态创建故事板,也无法为主线程上创建的窗口设置动画效果。
我错了Frame - 它在加载URL时阻塞了主线程。我总是使用WebBrowser控件,它是非阻塞的。
所以,你有两个选择(也许更多,但我将列出二):
- 在不同的线程创建一个动画窗口描述here。
- 使用WebBrowser而不是Frame。
我用样本更新了问题 – 2009-06-16 19:10:57