WPF 구현시 고민이 되는 부분이지만, 질문 자체는 일반적인 C#과 관련된 질문이라서 이곳에 문의드립니다. 현재 File이라는 클래스를 Collection으로 갖는 SelectedFiles에서 각각의 File의 다운로드를 처리하면서 이를 View 화면에서 각각 다운로드 상태를 보여주려고 합니다.
문제는 DownloadProgressCallback(링크)에서 다운로드의 상황 정보(e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage)를 처리합니다. 하지만 각각 File의 StatusFileDownload 에 해당 값을 할당해야 View에서 보여질텐데, 어떻게 접근해야 할지 고민이 됩니다. 좋은 방법이 있으시면 조언을 부탁드립니다.
namespace WPF_ParsingXML.ViewModels.Helper
{
public class DownloadHelper
{
static WindowsVM vm;
public DownloadHelper(WindowsVM _vm)
{
vm = _vm;
}
public static void DownloadFile(ObservableCollection<File> SelectedFiles, string path)
{
foreach (var sw in SelectedFiles)
{
string fileName = Path.Combine(path, sw.FileName);
Uri uri = new Uri(sw.OriginUri);
using (WebClient client = new WebClient())
{
client.DownloadProgressChanged += new
DownloadProgressChangedEventHandler(DownloadProgressCallback);
client.DownloadFileAsync(uri, fileName);
}
}
}
private static void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
{
// 각각의 파일의 StatusFileDownload = e.ProgressPercentage;
}
}
}
namespace WPF_ParsingXML.Models
{
public class File
{
public string FileName { get; set; }
public string OriginUri { get; set; }
public int StatusFileDownload { get; set; }
}
}
DownloadProgressChanged이벤트에 의해 수신된 값을 어떻게서든 최종적으로 화면에 표시를 해야 합니다. WPF에서 일반적인 접근은 바인딩인데, File을 INotifyPropertyChanged인터페이스를 구현해서 속성이 변경되었을 때 화면에 표시되도록 하면 좋습니다. 예를 들어 아래처럼 만들 수 있습니다.
public class FileInfo : INotifyPropertyChanged
{
private long _bytesReceived;
private long _totalBytesToReceive;
private DownloadState _downloadState;
public event PropertyChangedEventHandler? PropertyChanged;
public string Filename { get; }
public string OriginUri { get; }
public long BytesReceived {
get => _bytesReceived;
set
{
_bytesReceived = value;
OnPropertyChanged(nameof(BytesReceived));
}
}
public long TotalBytesToReceive
{
get => _totalBytesToReceive;
set
{
_totalBytesToReceive = value;
OnPropertyChanged(nameof(TotalBytesToReceive));
}
}
public DownloadState DownloadState
{
get => _downloadState;
set
{
_downloadState = value;
OnPropertyChanged(nameof(DownloadState));
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public FileInfo(string filename, string originUri)
{
this.Filename = filename;
this.OriginUri = originUri;
}
}
public enum DownloadState
{
Wait,
Downloading,
DownloadComplete
}