Replies: 11 comments 1 reply
-
You are thinking about this in reverse I think. Any long running tasks or actions can report using IProgress. However, the ProgressBar itself isn't a long running action. It is just a representation of progress and doesn't have any values of its own. It isn't doing any work, only displaying other work. So ProgressBar can consume IProgress information. However, it doesn't report it itself, it needs to come from a lower layer. If you application is pulling progress back out of a ProgressBar and using it elsewhere you have something designed wrong. There should be a common task in a lower layer that all code can consume progress information for. One of the consumers being the ProgressBar. |
Beta Was this translation helpful? Give feedback.
-
@robloo the IProgress is to be implemented in the controls displaying it, and consumed by the tasks. the pseudocode would look like this: View: class ProgressBar : IProgress<int>
{
// update the progress value of the progress bar
public void Report(int value) { this.Value = value; }
} MVVM class SomeMVVM
{
public async Task DoSomeExpensiveJob(IProgress<int> progressFeedback)
{
for(int i=0; i < 100; ++i)
{
progressFeedback.Report(i);
await Task.Pause(1000);
}
}
} that way, I can call DoSomeExpensiveWork, passing the ProgressBar control directly, to update the progress bar as the job progresses. |
Beta Was this translation helpful? Give feedback.
-
First of all, accessing visual element inside VM is bad practice. class SomeMVVM
{
public async Task DoSomeExpensiveJob(ProgressBar bar)
{
for(int i=0; i < 100; ++i)
{
bar.Value = i;
await Task.Pause(1000);
}
}
} |
Beta Was this translation helpful? Give feedback.
-
To do that you have to reference Avalonia in your MVVM project, with IProgress, you don't need to. |
Beta Was this translation helpful? Give feedback.
-
Hmm, that's you said |
Beta Was this translation helpful? Give feedback.
-
I will also add that using a progress bar itself to track progress rather than the underlying value is very odd. As mentioned it also breaks MVVM by having the progress bar be passed to the view model, giving the view model knowledge of the view. Even if it's only an interface, it's still not great. Typically the view reads the view model, not the other way around. |
Beta Was this translation helpful? Give feedback.
-
@vpenades why not having a property Percentage which you update from your task and which is bound to the Progressbar as any other value? |
Beta Was this translation helpful? Give feedback.
-
Everybody answering me it's assuming I have full control over the code, it's outdated, closed source libraries I'm calling. Also everybody is assuming mvvm while I'm actually doing this in code behind, that is, calling a background task that takes a iprogress interface as a parameter, on an event So that forces me to write a proxy object that implements iprogrees, so i can pass it as an argument, and updates the progressbar |
Beta Was this translation helpful? Give feedback.
-
Well you did give an MVVM example.
I don't see a problem with this. If you really want to do this, then this is the correct approach. With that said: You could even rewrite your own app's code to use MVVM, even with closed source code you can't modify. After all a view model is meant to wrap a model and not do very much on its own. You just need to pass a In any case, there are some possible technical problems with this. Avalonia/src/Avalonia.Controls/ProgressBar.cs Lines 224 to 231 in a5f5b8f The actual value of a progress bar is also a double. Avalonia/src/Avalonia.Controls/Primitives/RangeBase.cs Lines 111 to 118 in a5f5b8f Your example explicitly shows an integer. Assuming that is what your third party code wants, then you might need to wrap it regardless. Also what would the report value even be: This is also going to encourage "bad" code, especially for people using MVVM. As they will be tempted to just directly pass a reference to the progress bar to the VM instead of using the existing binding system which solves this problem already. |
Beta Was this translation helpful? Give feedback.
-
Note that even if you have a special case with existing code or other restraints, we cannot change the framework to accommodate this. It's against the MVVM design principles that the framework does need to follow here. If you want to deviate that's fine but it must be in your app only. I think this should be closed as by design. |
Beta Was this translation helpful? Give feedback.
-
My point of view is this:
So I was not seeing any harm for ProgressBar to implement an IProgress interface. To me, IProgress is almost an abstraction of a progress bar. Implementing it does not affect the current behavior and ony adds new ways of using the ProgressBar, its up to developers to use it or not. But certainly I failed to make my point, so closing. |
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem? Please describe.
ProgressBar control is used to display the progress of a task.
.Net has an interface, IProgress that is used as an abstracion of an UI object displaying the progress, so applications can report the progress of a task in a platform agnostic way.
So it would make sense that ProgressBar implements IProgress
Describe the solution you'd like
Describe alternatives you've considered
Right now I'm using a wrapper:
Additional context
.Net
Also has these types:
IProgress<T>
interfaceProgress<T>
classSystem.ComponentModel.ProgressChangedEventHandler
System.ComponentModel.ProgressChangedEventArgs
I think all these types are greatly underated, and ProgressBar could be made aware of them in some way.
No response
Beta Was this translation helpful? Give feedback.
All reactions