2012-08-24 31 views
0

我有以下简单的程序,在两个不同的页面之间来回切换帧的上下文。第一页只是一张照片,加载得很好,但第二页是一个框架,它被设置为实时天气雷达。 http://www.wunderground.com/auto/wxmap/IN/Carmel.html。当计时器将我的帧的上下文切换到天气雷达页面时,它只会开始加载并花费3-4秒的时间加载页面。在我创建页面并将其分配给_nextslide后,我检查了该框架的.Navigated事件,它几乎正好触发了,那么为什么我的框架等待直到页面显示为呈现网站?如果我能够显示网站完全加载,这将是完美的。框架需要加载一个网站之前页面显示

XAML:

<Page> 
    <Viewbox Stretch="Fill" Margin="15"> 
     <Frame Height="800" Width="1280" Content="{Binding SlideFrame}"/> 
    </Viewbox> 
</Page> 

C#:

private Page _slideFrame; 
private Page _nextFrame; 
private DispatcherTimer _slideChangeTimer; 
private int currentSlide = 1; 

// Property 
public Page SlideFrame 
{ 
    get { return _slideFrame; } 
    set 
    { 
     _slideFrame = value; 
     NotifyPropertyChanged("SlideFrame"); 
    } 
} 

// ViewModel Constructor 
public Page1ViewModel() 
{ 
    this.SlideFrame = new Slide1(); 
    _nextFrame = new Slide2(); 

    _slideChangeTimer = new DispatcherTimer(); 
    _slideChangeTimer.Interval = TimeSpan.FromSeconds(8); 
    _slideChangeTimer.Tick += new EventHandler(SlideChange_Tick); 
    _slideChangeTimer.Start(); 
} 

// 8 second timer event handler 
private void SlideChange_Tick(object sender, EventArgs e) 
{ 
    if (currentSlide == 1) 
    { 
     this.SlideFrame = _nextFrame; 
     _nextFrame = new Slide1(false); 
     currentSlide = 2; 
    } 
    else 
    { 
     this.SlideFrame = _nextFrame; 
     _nextFrame = new Slide2(); 
     currentSlide = 1; 
    } 
} 
+0

我看不到你在哪里设置'Frame'的Source属性。那是晚些时候,还是你为了简洁而忽略它? – CodingGorilla

+0

在SlideChange_Tick中,您是UI线程中的新SlideX。开始时,它将在UI线程上阻塞。它正在等待加载Slide2(),因为你_nextFrame = new Slide2();在Page1ViewModel中。 – Paparazzi

+0

我从来没有设置帧的来源,而是通过绑定将上下文设置为页面。这使我可以将源设置为我在其他XAML文件中设置的不同页面。 – JonD

回答

0

不使用框架或网页,但它显示了如何在后台获取数据不阻挡在计时器的UI。如果最后一个网页还没有被提取,你应该添加逻辑来等待。

<Button Grid.Row="0" Content="AmIhot" Click="onClick" Width="60" HorizontalAlignment="Left"/> 
<TextBlock Grid.Row="1" x:Name="hotText" /> 
<TextBlock Grid.Row="2" x:Name="revolvingText" Text="{Binding Path=RevolvingText, Mode=OneWay}" /> 

using System.ComponentModel; 
using System.Threading; 
using System.Threading.Tasks; 

namespace waste09 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     private System.Windows.Threading.DispatcherTimer _slideChangeTimer; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
      RevolvingText = "Starting text"; 
      _slideChangeTimer = new System.Windows.Threading.DispatcherTimer(); 
      _slideChangeTimer.Interval = TimeSpan.FromSeconds(8); 
      _slideChangeTimer.Tick += new EventHandler(SlideChange_Tick); 
      _slideChangeTimer.Start(); 
     } 

     // 8 second timer event handler 
     private void SlideChange_Tick(object sender, EventArgs e) 
     { 
      Task.Factory.StartNew(() => 
      { 
       // this will NOT block the UI 
       Thread.Sleep(4000); // simulate a long fetch 
       RevolvingText = "Fetched text " + Guid.NewGuid(); 
       NotifyPropertyChanged("RevolvingText"); 
      }); 
      RevolvingText = "Fetching data and UI not blocked "; 
      NotifyPropertyChanged("RevolvingText");    
     } 

     public string RevolvingText { get; private set; } 

     private void onClick(object sender, RoutedEventArgs e) 
     { 
      hotText.Text = "Yes you are hot " + Guid.NewGuid();  
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void NotifyPropertyChanged(String info) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 
    } 
} 
+0

我试图在Task.Factory.StartNew(()=> {})中生成我的页面;事件,但我最终得到错误: System.InvalidOperationException被用户代码未处理 消息=调用线程必须是STA,因为许多UI组件需要此。 有没有一种好的方法来加载网页的数据而不涉及UI线程? – JonD

+0

去标记为答案,因为它涵盖了我需要的一半。 – JonD

+0

您是否试图将页面放置在胎面上的框架中?您需要像使用公共属性一样来完成这个技巧,并且您无法直接从后台线程访问UI对象(框架)。或者你可以使用调度员。 – Paparazzi

相关问题