我正在使用wpf,我需要用类更新视图的元素。 所以,我有三个文件:
我需要更改的元素是标签。
为什么mainwindow自己的代码无法从函数中获取新名称并自行进行更改? 我希望在主窗口代码之外完成计算,以便获得清晰的代码。
我遇到的问题是在Utils.cs中我有两个函数,copy()和freeSpace()。复制功能复制文件并调用freeSpace。在自由空间中,我有一个循环,每隔10秒检查一次freeSpace,直到副本完成。因此,每10秒我需要更改代表可用空间的标签。
MainWindow.xaml
<Label x:Name="freeSpaceLabel"></Label>
MainWindow.xaml.cs
private void btnStart_Click(object sender, RoutedEventArgs e)
{
Utils u = new Utils();
u.copy();
}
Utils.cs
private void freeSpace(){
while (isFinish())
{
// Update the label
[...]
drive.TotalFreeSpace; //return an int, I just want to set this int to the label of my view.
[...]
Thread.Sleep(10000);
}
}
private void isFinish(){
// Return true if the copy is finish
// Return false if the copy is not finish
}
private void copy(){
//Copy a file
freeSpace();
}
我不认为传递视图是一个很好的解决方案。
感谢您的帮助!
答案 0 :(得分:0)
添加此代码以使您的任务异步:
private async void DoyourWorkHere()
{
await Task t = Task.Run( () =>
{
Utils u = new Utils();
u.copy();
} );
}
点击按钮调用此方法。
更新标签:
您可以创建事件和委托以将信息发送回MainWindow,或者您可以将MainWindow作为参数发送到util类,并从Util类调用公共属性来更新您的Label
答案 1 :(得分:0)
您可能根本不需要Util.cs。
您需要的是BackgroundWorker和ProgressChanged。试试这个:
<强> Stack_43489182.xaml:强>
<Window x:Class="Wpf.Test01.Stack_43489182"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wpf.Test01"
mc:Ignorable="d"
Title="Stack_43489182" Height="300" Width="300">
<DockPanel>
<Button x:Name="btnStartAsync" Content="Start Async" DockPanel.Dock="Top" Click="Button_Click" />
<ProgressBar x:Name="progressBar" Minimum="0" Maximum="100" />
</DockPanel>
</Window>
<强> Stack_43489182.xaml.cs:强>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Wpf.Test01
{
/// <summary>
/// Interaction logic for Stack_43489182.xaml
/// </summary>
public partial class Stack_43489182 : Window
{
private BackgroundWorker worker;
public Stack_43489182()
{
InitializeComponent();
this.worker = new BackgroundWorker();
this.worker.DoWork += Worker_DoWork;
this.worker.ProgressChanged += Worker_ProgressChanged;
this.worker.WorkerReportsProgress = true;
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar.Value = e.ProgressPercentage;
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
/** you need to put code from Util.cs here **/
int i = 1;
while(i <= 10)
{
this.worker.ReportProgress((int)((i / (double)10) * 100));
Thread.Sleep(1000);
i++;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
progressBar.Value = 0;
this.worker.RunWorkerAsync();
}
}
}
您甚至可以实施取消来停止您的操作。
请参阅此示例以了解如何使用BackgroundWorker: https://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners
如果您需要重复使用Util类
<强> Stack_43489182.xaml.cs 强>:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace Wpf.Test01
{
/// <summary>
/// Interaction logic for Stack_43489182.xaml
/// </summary>
public partial class Stack_43489182 : Window
{
private BackgroundWorker worker;
private Utils util;
public Stack_43489182()
{
InitializeComponent();
this.worker = new BackgroundWorker();
this.worker.DoWork += Worker_DoWork;
//this.worker.ProgressChanged += Worker_ProgressChanged;
this.worker.WorkerReportsProgress = true;
this.util = new Utils();
util.FreeSpace_ProgressChanged += Worker_ProgressChanged;
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => this.progressBar.Value = e.ProgressPercentage));
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
var utils = e.Argument as Utils;
if(utils != null)
{
utils.copy();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
progressBar.Value = 0;
this.worker.RunWorkerAsync(util);
}
public class Utils
{
public event ProgressChangedEventHandler FreeSpace_ProgressChanged;
private void freeSpace()
{
int i = 1;
while (!isFinished(i))
{
if(FreeSpace_ProgressChanged != null)
{
FreeSpace_ProgressChanged(i, new ProgressChangedEventArgs((int)((i / 10.0) * 100), null));
}
Thread.Sleep(1000);
i++;
}
}
private bool isFinished(int i)
{
// Return true if the copy is finish
// Return false if the copy is not finish
return i == 10 ? true : false;
}
public void copy()
{
//Copy a file
freeSpace();
}
}
}
}