在WPF/Silverlight中管理Frame导航事件与后台多线程

一、引言

在WPF的上位机开发中,当我们一个程序中有多个画面,在每个后面的后台可能需要多个进程需要对下位机的数据进行重复的读取或者处理,但当切换不同的界面后,page界面没有在视觉树上,那么需要结束后台的进程,若不结束那么再次回到该界面后台的进程将会重新拉起,极大的消耗内存。

二、基本思路:

在ViewModel中直接使用OnClosed方法并不直接可行,OnClosedWindow类的一个受保护方法,用于处理窗口关闭事件。ViewModel通常不直接引用View(如Window或UserControl),而是通过数据绑定和命令来交互。

View中LoadedUnloaded事件,并在事件处理程序中调用ViewModel中的一个方法,当page页面没有在视觉树上时,调用后台的关闭线程函数,销毁当前的线程。

三、示例代码

该示例是在page2viewmodel中进行了定时器操作,每隔一定的时间会执行一定的内容。需要对Timer_Tick这个线程进行关闭

  public Page2ViewModel() 
  {
      Page2Model.LineSeriesValues = new ChartValues<double> { 100, 100, 100, 100, 320, 540, 650, 444, 555 };
      timer = new DispatcherTimer();
      timer.Interval = TimeSpan.FromSeconds(1); // 设置间隔为1秒  
      timer.Tick += Timer_Tick; // 绑定Tick事件到处理方法  
      timer.Start(); // 启动定时器  

  }

  private void Timer_Tick(object sender, EventArgs e)
  {
      // 在这里执行你的操作
      Debug.WriteLine("page2定时器线程");
  }

 public void CloseTimer()
 {
     timer.Stop();
   
 }

使用LoadedUnloaded事件

每个页面(Page)都有LoadedUnloaded事件,这些事件在页面被加载到视觉树中和从视觉树中移除时触发。然而,这些事件并不直接指示页面是否“在显示”,因为页面可能在后台被加载或卸载,但用户仍然可以看到它(如果它是在一个未激活的标签页中)。

public MyPage()  
{  
    InitializeComponent();  
    this.Loaded += MyPage_Loaded;  
    this.Unloaded += MyPage_Unloaded;  
}  
  
private void MyPage_Loaded(object sender, RoutedEventArgs e)  
{  
    // 页面被加载到视觉树中  
    // 注意:这不一定意味着页面是可见的或活动的  
}  
  
private void MyPage_Unloaded(object sender, RoutedEventArgs e)  
{  
    // 页面从视觉树中移除  
    // 清理资源等操作  
}

但在无法直接调用ViewModl中的函数,需要先获取到这个DataContext作为ViewModel的实例,然后再调用其方法。

在你的视图(View)的后台代码(CS文件)中,当你设置DataContext之后,你可以这样调用CloseTimer()方法

public partial class MyPage : Page  
{  
    public MyPage()  
    {  
        InitializeComponent();  
  
        // 设置 DataContext  
        this.DataContext = new Page2ViewModel();  
  
        // 调用 DataContext 中的 CloseTimer 方法  
        // 首先,将 DataContext 转换为 Page2ViewModel 类型  
        if (this.DataContext is Page2ViewModel viewModel)  
        {  
            viewModel.CloseTimer();  
        }  
    }  
  
    // ... 其他方法和事件处理器  
}

所以在MyPage_Unloaded事件中放入if (this.DataContext is Page2ViewModel viewModel)  就可调用viewmodl中的函数

 public Page2()
 {
     InitializeComponent();
     this.DataContext = new Page2ViewModel();
     this.Loaded += MyPage_Loaded;
     this.Unloaded += MyPage_Unloaded;

 }
 private void MyPage_Loaded(object sender, RoutedEventArgs e)
 {
     // 页面被加载到视觉树中  
     // 注意:这不一定意味着页面是可见的或活动的  
 }

 private void MyPage_Unloaded(object sender, RoutedEventArgs e)
 {
     // 页面从视觉树中移除  
     Debug.WriteLine("Page2视觉树移除");
     if (this.DataContext is Page2ViewModel Page2viewModel)
     {
         Page2viewModel.CloseTimer();
     }
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值