❔ Where are commands usually defined?
I ask to see what is regarded as best practice. I have commands in my view models, but I was wondering where commands specific to a text box (editor) are defined. Are they defined in the editor's class, a viewmodel for the editor or somewhere else? How does this generalize to any control for that matter?
Think of commands specific to manipulating text only inside the editor.
9 Replies
I prefer to define commands where they're used, which in most cases means within the ViewModel itself.
Others like to separate things into different namespaces (sub-folders), sometimes even having things in their own projects.
But I like simplicity, so having commands in contextually related VM is one way to go.
This solves one particular problem - binding to commnds.
Since VM is typically the current DataContext, binding to commands is pretty straight-forward.
Thank you for you response. A follow up question if you don't mind:
If I have a main window with an editor and want to create editing commands like selecting, duplicating, deleting lines etc to which I can bind my menu items to, would I place these commands in the MainViewModel, create a ViewModel for the editor, or place it in the editor class itself?
I understand there are probably multiple ways to achieve this but I am just wondering if there is a standard/correct place to do this. (Thanks again)
It sounds like your editor class is a Model/Service that your ViewModel will use and have commands that call the editor methods. If you're designing a pretty simple application where the only function is to use this editor, you can just use the MainViewModel. But if you want to have multiple pages/views that don't all need the editor, you can make an EditorView and EditorViewModel that the MainView/MainViewModel can display
Thanks for the reply.
What I hope to gain is some good organization for the project. Basically it's like a notepad application, not very complex. The reason I want to avoid putting these commands in the MainViewModel is because I feel, organization-wise, there might be a better place to put them, I just don't know where that would make binding still easy. If I can actually have a file dedicated to just these commands that would actually be nice. Not sure if I should put them in the class/model of the texteditor.
As Vi Ness said, how you organize your views/viewmodels/commands depends on whether you want to support editing single file at a time or having multiple pages/editors open within the same application.
Single file editing is simple.
However, what I prefer now is to have my MainViewModel serve more like an orchestrator, like a container for everything else.
This basically means that it's there only to kickstart everything else and manage the entire application lifecycle.
My
MainWindow.xaml
typically only has a ContentControl
and then I assign the current view to it.
This way, you can support all kinds of scenarios.
Either way, if you want multi-file editor, then you're going to have a common set of commands that pply to all files, like Cut/Copy/Redo/Undo for example.
Such commands will reside in ViewModel for view that displays all currently open files, and then they operate on currently viewed file.
Simple hierarchy of views for such app
Here, MainEditorView is a UserControl, and
CommandPanel is just a bunch of buttons (for example) bound to commands in
MainEditorViewModel
Each
FileXTabItem is a
UserControl and if there are commands specific to each file (for example, if each file is using a different language or whatever, you can have those commands in a dedicated
FileXTabItemViewModel`
Note that this is just a pseudo-description of how to organize everything, it's not showing you exactly what is what.
So, to sum it up, I lke to place commands in ViewModels where they're used.
However, there are some who like to separate things further, they like more abstraction.
Such abstraction provides more flexibility, but requires you to thoroughly tink about how you want to use your app and then how you want to code everything in order to cover all use-cases.
Abstraction is great when you're planning ahead for more complex application structure, like, for example, if you'd like to support extensions, then designing everything to be more separated into units that can be easily swapped-out or extended is the way to go.Thanks for the clarification.
I really like the idea of the mainview as an orchestrator.
Yeah the app is single-file editing, only .txt nothing like language or such (basically windows notepad before they introduced tabs). Plus I don't use a command panel, I rely on the menus which maybe arguably is the same. I subclassed AvalonEdit and implemented in it the functions that I needed such as selecting the current line and such. I was mainly wondering where to go from there and since there were several things that worked I was wondering what to do. For example, it could be as simple as puttinh [RelayCommand] on top of my functions in the TextEditor class / or a variation of having the commands in there and binding the menu items by specifying the ElementName and Path. I could have also created another class where I instantiated all the commands and did CommandBindings.add in the TextEditor class.
The only part about putting these commands in a ViewModel is how do I actually execute the functionality (working with lines, carets, indices since the ViewModel doesn't technically know I am working with AvalonEdit (texteditor code https://gist.github.com/MarioFares/368fa202f77bd363a906f129363e3a28).
I think I might be doing things wrong
No, you're not doing things wrong, it's just that MVMV is not necessarily applicable on all use cases and, if you still want to use MVVM, some use-cases require more effort to do everything properly.
Yeah I agree completely with the more effort part, yet I'll stick with MVVM
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.