Updating datagrid gui from other threads
In wpf, I have an application that has a button and datagrid. The button over the datagrid adds an object to the datagrid called barProgress. The class barProgress contains one public int value called progress and is a default of 0 when initialized. The datagrid itself has two columns. Column one contains a progress bar for each object and Column two has a button that tells the progress of object to go up by one every second.
I understand creating/adding/binding objects to the datagrid and their values. I added background workers (running async of course) per object to update the object.progress by one per second.
Here's the problem.
I do not understand how to update the gui other than calling a method to refresh the ENTIRE datagrid. If I refresh the datagrid have issues with the buttons associated with each object being unable to be used the split second the datagrid refreshes.
Is there a concept I am missing? I do not have an observable collection or notify changes property for the class of bar progress. I believe that is what I need but I also cannot find a good example of how those work and I wonder that even if I get those to work does that mean the button per object is still going to refresh and be disabled for a split second?
This is my code.
This is just a demo for this specific issue that pertains to a much bigger project I have where refreshes are much more rapid and button access really matters.
GitHub
GitHub - Dingus115/multithreaded-Datagrid
Contribute to Dingus115/multithreaded-Datagrid development by creating an account on GitHub.
15 Replies
i noticed that you named your project mvvm, but what i see that is no mvvm
backgroundworker ha a event oncompleted that will be called on the ui thread when the backgroundworker finishes.. making manual dispatching unneccessary
im not too familiar with datagrid, tbh i would have expected that when you add item that it will be shown directly
I am trying to learn mvvm right now to see if maybe that was the aproach that I needed. I'm just having a lot of trouble wrapping my head around the concepts of the viewmodel that I see make into a INotifyClass. If you know/have any super simple examples of a mvvm approach with just like a single variable to change that would be greatly appreaciated!
I believe that even if I got mvvm approach working though that the datagrid would still need to refresh to show the objects updated progress through its progress bar unless there is some magical sorcery I dont know that allows a single cell to refresh rather than the row.
what you are missing in your case is just the notify propertychanged in class1
then you can skip the refreshstuff
because it will just update the progress and nothing else
i was playing around with it a bit
and removed the refreshbutton from xaml
when you click on reset it will just add 10 to progress and update
you're an actual godsend. unfortunately I still cant wrap my head around the onpropertychanged function. I will do research to break that function down so I understand what the definition of each part means!
now to the explanation why it this works or more why you needed the refresh before:
you created a a binding to a property that had didnt notify for changes, so the ui didnt know when to update...
that was the reason you had to invoke refresh so the datagrid can pull the new data
now that notify property changed is implemented the ui gets an event when the progress has been changed and can update it directly thats what inotifypropertychanged is for
there is also icollectionchanged that updates the ui if a collection got longer/shorter
bindings in the xaml are basicly the way to tell wpf to listen to these events
sorry but i dont want to get to much into detail about mvvm.. its late and i would need to rite a book..xD
youre totally fine. I really appreciate the help! I just want to make sure I understand what I am doing wrong and understand the concepts behind what I need rather than just copy paste. again thank you so much!
if you have specific questions i might answer them but explaing mvvm from scratch is a nono for me today
'protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}'
Mainly what does "[CallerMemberName] string name = null" even define. Is this the object, the binding name, or the property of object (and if property does that mean that then the function uses this method to update other columns of different values that change as well?)
[CallerMemberName] is a special attribute provided by dotnet that puts the nameof the member that calls that method into that string wihtout having to do it manually
so i this case progress calls OnPropertyChanged so name will be "progress"
when invoking PropertyChanged, wpf needs to know what to update in this case progress
string name = null is for the case if you want to update another property then you have to provide the name yourself in OnPropertyChanged();
eg OnPropertyChanged("someotherprop");
sweet. If another column and property was made called "RandomInt", then would that mean that
1. I would need to set up another "public int RandomInt" with get/set where I would also need to pass the onpropertyChanged event handler to
2. that "string? name =" would equal "RandomInt" as the value?
asuming i understood you correctly, yes
this is amazing 😀 thank you so much for the help. I'll need to implement this into a much larger project next week and thanks to you now it won't be nearly as painful now that I understand it.
i have quickly thrown something together
so that we are talking about the same stuff
I really appreciate your time! That was exactly what I was talking about
no problem.. you showed genuine interested, and knew how to ask a question.. thats when i go the extramile ;)