0

I think I'm confusing some concepts and words here. It's easiest to describe in code.

What I have:

EditorVM

var webClient = new WebClient();
webClient.DownloadProgressChanged += (s, e) => pageVm.LoadingProgressValue = e.ProgressPercentage;
pageVm.WrapInDeterminedLoading(webClient.DownloadFileTaskAsync(new Uri(sourceUri), localPath), "Loading Video..");

PageVM

public async void WrapInDeterminedLoading(Task task, string text)
{
    LoadingProgressValue = 0;
    IsLoading = true;
    IsLoadingProgressIndeterminate = false;
    LoadingText = text;
    await task;
    IsLoading = false;
}

I'm wrapping all the logic I need to show something as loading within my PageVm. I want to do the DownloadProgressChanged line within the PageVM. I tried simply putting a DownloadProgressChangedEventHandler as a method argument, but I feel it's really not what I want.

How can I set it up in a way so that I'm forced to set up some kind of value to the LoadingProgressValue?

I feel the third line does not belong in EditorVM. It's manually handling details of how loading works. I would like to have the PageVM class deal with that. But I need to react to the webclient's event somehow...

What I want and expected I could do somehow:

EditorVM:

var webClient = new WebClient();
pageVm.WrapInDeterminedLoading(webClient.DownloadFileTaskAsync(new Uri(sourceUri), localPath), "Loading Video..", webClient.DownloadProgressChanged);

PageVM

public async void WrapInDeterminedLoading(Task task, string text, ChangedHandler handler)
{
    handler += (s, e) => LoadingProgressValue = e.ProgressPercentage;
    LoadingProgressValue = 0;
    IsLoading = true;
    IsLoadingProgressIndeterminate = false;
    LoadingText = text;
    await task;
    IsLoading = false;
}
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • If I understand correctly, your question boils down to this: you want PageVM to be able to subscribe to the `DownloadProgressChanged` event without either of a) EditorVM being involved, and b) PageVm knowing anything about `WebClient`. Is that correct? – Peter Duniho Mar 24 '20 at 19:23
  • Yes. 100% correct. And if at all possible, not only DownloadProgressChanged, but all kinds of -ProgressChanged events. – GradientJagger Mar 24 '20 at 19:28
  • For better or worse, what you want to do is not literally possible in C#. See marked duplicates. There are techniques you can use to abstract the operation a bit; these are described in the marked duplicates. As an example, you could pass `Action` to the `WrapInDeterminedLoading()` method. The value to pass would be `d => webClient.DownloadProgressChanged += d`, then in `WrapInDeterminedLoading()`, would be used as e.g. `subscribeEvent((s, e) => Loading ProgressValue = e.ProgressPercentage);`. – Peter Duniho Mar 24 '20 at 19:32
  • All that said, your event handler necessarily knows about the `WebClient`, because the `DownloadProgressChanged` event is specific to that object. You'd have to generalize further to avoid that. And without generalizing further, I'm not sure whether there's really that much value in decoupling the classes like that (even though decoupling in general is a very good idea). – Peter Duniho Mar 24 '20 at 19:33
  • Yea i saw those but didnt really understand. I guess it just doesnt work. Seems strange to me. – GradientJagger Mar 24 '20 at 19:38
  • There may be other languages where it could work. But C# just isn't like that. For what it's worth, properties are exactly the same. In C#, both properties and events are just a thin veneer over a pair of methods (`get` and `set` for properties, `add` and `remove` for events). And C# doesn't provide a syntax for passing those pairs of methods, or even of gaining access to them directly (you can do it via reflection, as noted in one of the answers on the marked duplicates, but that's pretty messy and worse than whatever drawbacks the coupling has). – Peter Duniho Mar 24 '20 at 19:41
  • I turned it around and wrote an extension method for the webclient that takes a PageVM, a task and a string. Its not a bad compromise i think. – GradientJagger Mar 24 '20 at 19:50

0 Answers0