this is a question that has to do with WPF mostly and it is a “shot in the dark” because it is a weird problem and I do not know if anyone had it, but I can at least try, because I tried everything and it literally took days out of my life…still unsolved.
- create a new Rhino Plug and
- add a simple WPF Window to it, and then
- create an empty ViewModel class, and just add this to the Window Xaml (those are literally all the steps):
I cannot see the window anymore in the Design View:
I tried approximately 15 different solutions from the internet because it seems like a pretty common problem(rebuilding, deleting .vs folder, changing NET Framework…installing VS 2022, etc etc)…nothing helped. The project builds and works, but I cannot see the Window in the Design View. It says that it does not exist (although it does):
If I however make a new WPF App from scratch and do these few steps - I do not have this problem…all works fine…so I wonder what is there missing when I do this inside a new Rhino Plug-in.
P.S. I realized that dealing with this in code behind and not in XAML can probably solve the problem…but I wil leave this question here anyway since I am interested in the cause…and see if anyone knows it.
Please share the Xaml and the ViewModel.
If you want to inject the ViewModel during design-time, you either inject the Viewmodel under
<d:DataContext>...<d:DataContext> where the d stands for design time within your window or user control.
Or better, you mock the data of your child controls. E.g. if you write
<Textbox d:Text="Some Text"/> you can feed in data only visible in the designer. Not sure if this is the issue, but again, the point of MVVM is the separation of concern. In an ideal world, this means your UI should function with any data coming from any given ViewModel, as long as bindings and command-routes match. Anything logical belongs to the VM, so that it can be (unit-)tested there in isolation. Now sometimes this is not so easy, a code-behind approach is sometimes just simpler and more practical. But for the average view, you shouldn’t need to inject a viewmodel to expose it in the designer.
Some more things:
The View should never reference a concrete ViewModel. The View shouldn’t know the ViewModel at all.
While in design time, your code changes are not compiled yet. If it doesn’t find something or fails to build, then this is because you expect the designer to have data which is not in memory yet. Therefore, for converter, validation rules etc. you always need to successfully compile before you can use them.
Just to clarify.
This is what I usually do with my main window at the app startup.
If you do it like this, you keep it separated and the error should also disappear:
MainWindow = new MainView();
MainWindow.DataContext = new MainViewModel();
With this approach the view doesn’t know the viewmodel and can easily be replaced.
It is always tricky to change the DataContext from inside the view.
For any child view you bind the data context in the viewmodel from the parent viewmodel.
This can/should be done within the XAML with a Databinding
I see a lot of stack-overflow posts setting the ViewModel directly from within the View.
It is not wrong, but its breaking the pattern for no reason and I’m not so sure if this is the
intended way. Because it clues the view and viewmodel together.
On top of that, with the code above you can provide parameters.
If I want to open a new window, I do it like above but I wrap the code inside a ‘ViewService’. This is untestable code and should only be used to create views.