2009-06-15 36 views
1

我有一个框架和一个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); 
    } 
} 

直到加载页面之后才显示椭圆。

回答

0

WPF动画启动时不能被主线程阻塞。故事板在自己的线程中运行,并且呈现发生在WPF呈现线程中,这与主线程不同。另外,我相信帧加载也是非阻塞的。

所以你的代码还有其他的东西,你为什么不把它发布在这里,以便我们理解。

编辑:我错了故事板。由于资源是在主线程上创建的,因此它在相同的主线程中运行。即使您动态创建故事板,也无法为主线程上创建的窗口设置动画效果。

我错了Frame - 它在加载URL时阻塞了主线程。我总是使用WebBrowser控件,它是非阻塞的。

所以,你有两个选择(也许更多,但我将列出二):

  • 在不同的线程创建一个动画窗口描述here
  • 使用WebBrowser而不是Frame。
+0

我用样本更新了问题 – 2009-06-16 19:10:57

相关问题