MVVM isn't like a religion where the inquisition drags an unbeliever away to torture and burn at the stake.
If you worked in a team then your code wouldn't get past the first merge request review. But whoever reviewed it would presumably have told you "this is bad" when they rejected it. And told you what accepted practice is.
That hasn't happened so I guess there's just you working on this and you can do what you like.
Having said that.
That code does not follow the MVVM pattern.
The view shouldn't go get some data to pass into a viewmodel. It's the viewmodel's job to adapt and present it with data.
The model isn't a class like in MVC usage, it's whatever provides data. Often a wrapper round a Rest call like httpget.
I recommend viewmodel first wherever practical and a single window application.
The view is then a datatemplate that data from the viewmodel is templated out into.
Like this how to open new WPF window in stack panel in WPF mainwindow?
At it's simplest, mainwindowviewmodel controls what viewmodel is current and that in turn is templated.
You'd want more sophistication in practice.
In this though, the view does not go get it's viewmodel.
Let's differentiate between parent viewmodels and children. Frequently you will have a viewmodel for viewing or editing a bunch of things. See all invoices for a client or some such.
That parent viewmodel needs a bunch of data.
A pattern I have frequently used is to separate out instantiation of that parent viewmodel from fetching data.
The ctor is pretty much empty and there's an async task which will get any required data. You can instantiate and inject services, present your viewmodel so the view starts to render. Then separately and asynchronously get your data. The view appears with it's loading spinner, the task completes and the spinner is collapsed the data shown.
That task can be included in an interface all viewmodels implement so you can then generically instantiate a vm (usually out a di container) and await a GetMyData Task.
In a commercial apps the model is a call to a separate web site - web api or node or whatever.
I recommend separation of classes that model returns from viewmodels. Even if you're "just" using dapper to fill a class. Even if you have entity framework and those entity classes look like maybe you could "just" use them. Think of how you get that data as a separate model with separate dto classes.
Copying property A from one class to another makes for some repetitive tedious code. There are packages will make that easy. I like automapper. You then have a fracture point where you can conveniently insert any translation. Have a string in your model but want a datetime in your viewmodel? No problem you just put a bit of a lambda in the automapper definition.
When you want to commit data, you then do the reverse viewmodel => automapper => model.
When you want to edit a viewmodel automapper has another bonus in that you can deep copy any instance easily. Edit a copy. If it fails valiation then you can bin that copy and your original is pristine.
In this way though.
Any Viewmodel is presented to the UI and templated into controls.
A parent viewmodel gets it's data by calling a service.
That service "just" returns or accepts dto from the VMs perspective. The service hides whatever is beyond it.
Perhaps some prototyp-ish code.
Let's assume we have a small app and no web server. There's just a repository returns data.
We have SomeViewModel and SomeViewmodel needs a collection of Somes.
Where does it get them?
Out a service which supplies a List where that Some is a DTO.
Where's it get that service?
That's resolved out dependency injection so it's passed into the ctor. The view knows nothing about any viewmodels, repositories or anything.
SomeDataRepository can have an interface so you resolve against ISomeDataRepository and you can switch out moqs if you want to for unit testing. Or some other implementation of the repository if your requirement is very very unusual.
public SomeViewModel(SomeDataRepository repos)
{
In SomeViewModel there's a list filled using some mapper conversion
SomeList = MapperConversion<SomeViewModel>(await repos.GetSomeAsync);
The repository Some dto is somewhat loosely coupled with the SomeViewModel since mapper copies property to property.