我有一个带有Frame和TreeView的WPF应用程序。 TreeView显示我的应用程序的菜单,当单击一个项目时,框架通过调用Navigate
显示该菜单项的内容。该调用有时需要几秒钟,导航完成时会阻止UI。
我有一个动画旋转圆圈的控件(我称之为WaitIcon),我想在框架加载时显示它,但它没有出现(并且即使它确实出现也不会旋转),因为UI线程被阻止加载Frame的内容。我无法在后台线程上调用Navigate
,因为该帧由UI线程拥有。有框架加载时显示WaitIcon的方法吗?可能通过创建拥有WaitIcon的第二个线程?
更新 - 显示以下问题的示例代码:
这是主窗口。我刚刚使用动画Ellipse来模拟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 :(得分:0)
WPF动画启动时,主线程无法阻止。故事板在其自己的线程中运行,并且渲染发生在WPF渲染线程中,该线程与主线程不同。另外,我相信Frame加载也是非阻塞的。
所以你的代码还有其他的东西,你为什么不在这里发帖,所以我们可以理解。
编辑:我在故事板上错了。由于资源是在主线程上创建的,因此它在同一主线程中运行。即使您动态创建了一个故事板,它也无法从主线程上创建的窗口中设置对象的动画。我错了Frame - 它在加载URL时阻塞了主线程。我总是使用WebBrowser控件,它是非阻塞的。
所以,你有两个选择(可能更多,但我会列出两个):