我正在使用Silverlight 4导航框架并且页面需要一些时间来加载(通常绑定到大量数据)。
我在MainFrame上放了一个IsBusy SL Toolkit控件,当你点击导航到另一个页面时我想把它设置为Busy,当另一个页面加载完毕后我将它设置为NotBusy。
为了保持简单并让它首先工作,我排除了MVVM并且只使用了代码隐藏调用,但我的IsBusy控件从未出现过。我认为这是一个UI线程问题,但我需要一些帮助。
编辑:在一个简单的页面上,IsBusy控件正在出现,但只有一旦加载了请求的页面(然后它被关闭,因此你永远不会看到它)。我需要调用页面来调用父框架上的IsBusy控件并在它尝试甚至加载下一页之前显示它...
以下是我的MainFrame页面上的XAML:
<Grid x:Name="LayoutRoot">
<navigation:Frame
x:Name="ContentFrame"... NavigationFailed="ContentFrame_NavigationFailed">
<navigation:Frame.UriMapper>
...
</navigation:Frame.UriMapper>
</navigation:Frame>
<telerik:RadBusyIndicator
x:Name="busyIndicator"
BusyContent="Please wait..." />
</Grid>
以下是导航到另一个页面的页面上的代码:
private void workorderButton_Click(object sender, RoutedEventArgs e)
{
((MainPage) App.GetApp.RootVisual).busyIndicator.IsBusy = true;
NavigationService.Navigate(new Uri("WorkOrderView", UriKind.Relative));
}
然后在目标网页上:
public WorkOrderView()
{
InitializeComponent();
((MainPage)App.GetApp.RootVisual).busyIndicator.IsBusy = false;
}
我尝试了很多不同的选项,但指标从未出现过。我尝试将其包装在一些线程代码中然后显示但是抛出了无效的交叉线程异常。
我使用此代码(同一页面上的按钮)测试了XAML,它工作正常(显示和隐藏):
private void btnIsBusy_Click(object sender, RoutedEventArgs e)
{
((MainPage)App.GetApp.RootVisual).busyIndicator.IsBusy = true;
ThreadPool.QueueUserWorkItem((state) =>
{
Thread.Sleep(3 * 1000);
Dispatcher.BeginInvoke(() => ((MainPage)App.GetApp.RootVisual).busyIndicator.IsBusy = false);
});
}
我确定它与UI线程有关...任何帮助都赞赏!
由于
答案 0 :(得分:0)
我建议您查看Silverlight 4中引入的INavigationContentLoader
界面,它为您提供了一个很好的位置,可以挂钩导航系统并“全局”(在所有导航中)执行此类操作。
请参阅David Poll关于做一些非常简单的博客文章,在这里:http://www.davidpoll.com/2010/02/01/on-demand-loading-of-assemblies-with-silverlight-navigation-revisited-for-silverlight-4-beta/
他碰巧正在做一些比你需要的更复杂的事情(从远程XAP加载页面),但看看他正在使用BusyIndicator控件做什么,并希望很容易看到如何剥离和使用该部分(他为他所有的东西提供了资源,所以你可以随心所欲地挖掘。)
如果这看起来比您的项目所需的工作更多,那么您可以实现它的另一种方法是挂钩Frame.Navigated
和Frame.Navigating
- 在托管主机的控件上创建一个布尔属性Frame,在Frame.Navigating
中将其设置为true,在Frame.Navigated
中将其设置为false,并使用数据绑定将该Boolean属性绑定到您的IsBusy控件。