Wpf 框架需要在页面显示之前加载网站
我有一个简单的程序,可以在两个不同的页面之间来回切换帧的上下文。第一页只是一张图片,可以正常加载,但第二页是一个帧,其源设置为实时天气雷达。 . 当计时器将我的帧的上下文切换到天气雷达页面时,它才开始加载,并在加载页面的前3-4秒钟内花费时间。我检查了框架的.Navigated事件,在我创建页面并将其分配给_nextslide之后,它会立即触发,那么为什么我的框架会等待页面显示以呈现网站?这将是完美的,如果我可以显示该网站完全加载 XAML:Wpf 框架需要在页面显示之前加载网站,wpf,frame,Wpf,Frame,我有一个简单的程序,可以在两个不同的页面之间来回切换帧的上下文。第一页只是一张图片,可以正常加载,但第二页是一个帧,其源设置为实时天气雷达。 . 当计时器将我的帧的上下文切换到天气雷达页面时,它才开始加载,并在加载页面的前3-4秒钟内花费时间。我检查了框架的.Navigated事件,在我创建页面并将其分配给_nextslide之后,它会立即触发,那么为什么我的框架会等待页面显示以呈现网站?这将是完美的,如果我可以显示该网站完全加载 XAML: 不使用框架或网页,但它显示了如何在后台获取数据,以避
不使用框架或网页,但它显示了如何在后台获取数据,以避免在计时器中阻塞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));
}
}
}
}
使用系统组件模型;
使用系统线程;
使用System.Threading.Tasks;
命名空间浪费09
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口,INotifyPropertyChanged
{
private System.Windows.Threading.Dispatchermer\u slideChangeTimer;
公共主窗口()
{
初始化组件();
this.DataContext=this;
RevolvingText=“起始文本”;
_slideChangeTimer=new System.Windows.Threading.Dispatchermer();
_slideChangeTimer.Interval=从秒开始的时间跨度(8);
_slideChangeTimer.Tick+=新事件处理程序(SlideChange\u Tick);
_slideChangeTimer.Start();
}
//8秒计时器事件处理程序
私有void SlideChange_勾选(对象发送方,事件参数e)
{
Task.Factory.StartNew(()=>
{
//这不会阻止用户界面
Thread.Sleep(4000);//模拟长取
RevolvingText=“获取的文本”+Guid.NewGuid();
NotifyPropertyChanged(“RevolvingText”);
});
RevolvingText=“正在获取数据和UI未被阻止”;
NotifyPropertyChanged(“RevolvingText”);
}
公共字符串RevolvingText{get;private set;}
private void onClick(对象发送方,RoutedEventArgs e)
{
hotText.Text=“是的,您很热”+Guid.NewGuid();
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串信息)
{
if(PropertyChanged!=null)
{
PropertyChanged(此,新PropertyChangedEventArgs(信息));
}
}
}
}
我看不到您在哪里设置帧的源属性。这是稍后才会出现的,还是为了简洁起见,您省略了它?在SlideChange_Tick中,您是UI线程上的新SlideX。在启动时,它将在UI线程上阻塞。它正在等待加载Slide2(),因为您_nextFrame=newslide2();在Page1ViewModel中,我从未设置框架的源,而是通过绑定将上下文设置为页面。这允许我将源设置为在其他XAML文件中设置的不同页面;事件,但我最终得到了错误:System.InvalidOperationException未被用户代码消息处理=调用线程必须是STA,因为许多UI组件都需要它。有没有一种好方法可以在不涉及UI线程的情况下加载网页的数据?将标记为答案,因为它涵盖了我需要的内容的一半。您是否尝试将网页放置在踏板上的框架中?您需要像我对公共属性所做的那样,直接从后台线程访问UI对象(框架)。或者您可以使用dispatcher。
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;
}
}
<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));
}
}
}
}