C# 在WPF进度条中通过单击按钮报告以下方法的进度?
我有一个按钮点击执行的以下方法:C# 在WPF进度条中通过单击按钮报告以下方法的进度?,c#,wpf,C#,Wpf,我有一个按钮点击执行的以下方法: private void CopyDirectoriesAndFiles(string source, string target, string[] excludedFolders) { foreach (string dir in Directory.GetDirectories(source, "*", System.IO.SearchOption.AllDirectories))
private void CopyDirectoriesAndFiles(string source, string target, string[] excludedFolders)
{
foreach (string dir in Directory.GetDirectories(source, "*", System.IO.SearchOption.AllDirectories))
if (!excludedFolders.Contains(dir))
Directory.CreateDirectory(target + dir.Substring(source.Length));
foreach (string file_name in Directory.GetFiles(source, "*.*", System.IO.SearchOption.AllDirectories))
if (!File.Exists(Path.Combine(target + file_name.Substring(source.Length))))
File.Copy(file_name, target + file_name.Substring(source.Length));
}
按钮单击还有一些其他方法,但它们运行的时间并不长,但即使如此,我如何为每个运行的按钮显示和更新进度条呢。我放了一个文本框,但它只在完成所有操作后写入文本框。我的按钮顺序可能如下所示:
InitializeStuff();
CopyFiles();
CleanUp();
进度条不是绝对必要的,尽管很好。如果我能让我的文本框在每次方法完成时更新,而不是在最后更新,那就太好了
我有一个按钮点击执行的以下方法:
private void CopyDirectoriesAndFiles(string source, string target, string[] excludedFolders)
{
foreach (string dir in Directory.GetDirectories(source, "*", System.IO.SearchOption.AllDirectories))
if (!excludedFolders.Contains(dir))
Directory.CreateDirectory(target + dir.Substring(source.Length));
foreach (string file_name in Directory.GetFiles(source, "*.*", System.IO.SearchOption.AllDirectories))
if (!File.Exists(Path.Combine(target + file_name.Substring(source.Length))))
File.Copy(file_name, target + file_name.Substring(source.Length));
}
不应该这样。这将使您的UI冻结太久
使用后台工作人员,以下是使用MVVM的完整工作模型: 观点:
<Window x:Class="CopyFiles.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:model="clr-namespace:CopyFiles">
<Window.DataContext>
<model:CopyModel />
</Window.DataContext>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Name="sourceLabel">Source</Label>
<TextBox Text="{Binding Source, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1" Name="sourceTextBox" Margin="5"/>
<Label Grid.Row="1" Grid.Column="0" Name="destinationLabel">Destination</Label>
<TextBox Text="{Binding Destination, Mode =TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1" Name="destinationTextBox" Margin="5" />
<Button Command="{Binding CopyCommand}" Grid.Row="2" Grid.ColumnSpan="2" Content="Copy" Name="copyButton" Width="40" HorizontalAlignment="Center" Margin="5"/>
<ProgressBar Visibility="{Binding CopyInProgress, Converter={StaticResource booleanToVisibilityConverter}}" Value="{Binding Progress}" Grid.Row="3" Grid.ColumnSpan="2" Height="20" Name="copyProgressBar" Margin="5" />
</Grid>
</Window>
来源
目的地
ViewModel:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using Microsoft.Practices.Prism.Commands;
namespace CopyFiles
{
public class CopyModel: INotifyPropertyChanged
{
private string source;
private string destination;
private bool copyInProgress;
private int progress;
private ObservableCollection<string> excludedDirectories;
public CopyModel()
{
this.CopyCommand = new DelegateCommand(ExecuteCopy, CanCopy);
this.excludedDirectories = new ObservableCollection<string>();
}
public event PropertyChangedEventHandler PropertyChanged;
public string Source
{
get { return source; }
set
{
source = value;
RaisePropertyChanged("Source");
CopyCommand.RaiseCanExecuteChanged();
}
}
public string Destination
{
get { return destination; }
set
{
destination = value;
RaisePropertyChanged("Destination");
CopyCommand.RaiseCanExecuteChanged();
}
}
public bool CopyInProgress
{
get { return copyInProgress; }
set
{
copyInProgress = value;
RaisePropertyChanged("CopyInProgress");
CopyCommand.RaiseCanExecuteChanged();
}
}
public int Progress
{
get { return progress; }
set
{
progress = value;
RaisePropertyChanged("Progress");
}
}
public ObservableCollection<string> ExcludedDirectories
{
get { return excludedDirectories; }
set
{
excludedDirectories = value;
RaisePropertyChanged("ExcludedDirectories");
}
}
public DelegateCommand CopyCommand { get; set; }
public bool CanCopy()
{
return (!string.IsNullOrEmpty(Source) &&
!string.IsNullOrEmpty(Destination) &&
!CopyInProgress);
}
public void ExecuteCopy()
{
BackgroundWorker copyWorker = new BackgroundWorker();
copyWorker.DoWork +=new DoWorkEventHandler(copyWorker_DoWork);
copyWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(copyWorker_RunWorkerCompleted);
copyWorker.ProgressChanged += new ProgressChangedEventHandler(copyWorker_ProgressChanged);
copyWorker.WorkerReportsProgress = true;
copyWorker.RunWorkerAsync();
}
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if(handler != null)
{
var eventArgs = new PropertyChangedEventArgs(propertyName);
handler(this, eventArgs);
}
}
private void copyWorker_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
this.CopyInProgress = true;
worker.ReportProgress(0);
var directories = Directory.GetDirectories(source, "*", System.IO.SearchOption.AllDirectories);
var files = Directory.GetFiles(source, "*.*", System.IO.SearchOption.AllDirectories);
var total = directories.Length + files.Length;
int complete = 0;
foreach (string dir in directories)
{
if (!ExcludedDirectories.Contains(dir))
Directory.CreateDirectory(destination + dir.Substring(source.Length));
complete++;
worker.ReportProgress(CalculateProgress(total, complete));
}
foreach (string file_name in files)
{
if (!File.Exists(Path.Combine(destination + file_name.Substring(source.Length))))
File.Copy(file_name, destination + file_name.Substring(source.Length));
complete++;
worker.ReportProgress(CalculateProgress(total, complete));
}
}
private static int CalculateProgress(int total, int complete)
{
// avoid divide by zero error
if (total == 0) return 0;
// calculate percentage complete
var result = (double)complete / (double)total;
var percentage = result * 100.0;
// make sure result is within bounds and return as integer;
return Math.Max(0,Math.Min(100,(int)percentage));
}
private void copyWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.Progress = e.ProgressPercentage;
}
private void copyWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.CopyInProgress = false;
}
}
}
使用系统;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.IO;
使用Microsoft.Practices.Prism.Commands;
命名空间复制文件
{
公共类CopyModel:INotifyPropertyChanged
{
私有字符串源;
专用字符串目的地;
私人bool copyInProgress;
私人投资进展;
不包括目录的私人可观测集合;
公共复制模型()
{
this.CopyCommand=newdelegatecommand(ExecuteCopy、CanCopy);
this.excludedDirectories=新的ObservableCollection();
}
公共事件属性更改事件处理程序属性更改;
公共字符串源
{
获取{返回源;}
设置
{
来源=价值;
RaisePropertyChanged(“来源”);
CopyCommand.RaiseCanExecuteChanged();
}
}
公共字符串目的地
{
获取{返回目的地;}
设置
{
目的地=价值;
RaisePropertyChanged(“目的地”);
CopyCommand.RaiseCanExecuteChanged();
}
}
公共图书馆复制程序
{
获取{return copyInProgress;}
设置
{
copyInProgress=值;
RaisePropertyChanged(“CopyInProgress”);
CopyCommand.RaiseCanExecuteChanged();
}
}
公共信息技术进步
{
获取{返回进度;}
设置
{
进步=价值;
RaiseProperty变更(“进度”);
}
}
公共可观测集合(不包括目录)
{
获取{return excludedDirectories;}
设置
{
excludedDirectories=值;
RaiseProperty变更(“不包括目录”);
}
}
公共DelegateCommand CopyCommand{get;set;}
公共图书馆
{
返回(!string.IsNullOrEmpty(源)&&
!string.IsNullOrEmpty(目标)&&
!CopyInProgress);
}
public void ExecuteCopy()
{
BackgroundWorker copyWorker=新的BackgroundWorker();
copyWorker.DoWork+=新的DoWorkEventHandler(copyWorker\u DoWork);
copyWorker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(copyWorker\u RunWorkerCompleted);
copyWorker.ProgressChanged+=新的ProgressChangedEventHandler(copyWorker\u ProgressChanged);
copyWorker.WorkerReportsProgress=true;
copyWorker.RunWorkerAsync();
}
私有void RaisePropertyChanged(字符串propertyName)
{
var handler=PropertyChanged;
if(处理程序!=null)
{
var eventArgs=新的PropertyChangedEventArgs(propertyName);
处理程序(此,eventArgs);
}
}
私有void copyWorker_DoWork(对象发送方,DoWorkEventArgs e)
{
var worker=发送方作为后台工作人员;
this.CopyInProgress=true;
工人进度报告(0);
var directories=Directory.GetDirectories(source,“*”,System.IO.SearchOption.AllDirectories);
var files=Directory.GetFiles(源“***”,System.IO.SearchOption.AllDirectories);
var total=目录.Length+文件.Length;
int complete=0;
foreach(目录中的字符串目录)
{
如果(!ExcludedDirectories.Contains(dir))
Directory.CreateDirectory(destination+dir.Substring(source.Length));
完全++;
worker.ReportProgress(CalculateProgress(总计,完成));
}
foreach(文件中的字符串文件名)
{
如果(!File.Exists(Path.Combine(目标+文件名.Substring(source.Length)))
Copy(文件名,目的地+文件名.Substring(source.Length));
完全++;
worker.ReportProgress(CalculateProgress(总计,完成));
}
}
专用静态整数计算器进程(整数总计,整数完成)
{
//避免被零除的错误
如果(总计==0)返回0;
//计算完成百分比
var结果=(双)完成/(双)总计;
风险值百分比=结果*100.0;
//确保结果在范围内,并以整数形式返回;
返回Math.Max(0,Math.Min(100,(int)百分比));
}
私有void copyWorker\u ProgressChanged(对象发送方,progresschangedventargs e)
{
这是我们的进步=