Seperate ViewModel and View without using Code Behind

Answered Seperate ViewModel and View without using Code Behind

  • Tuesday, March 06, 2012 4:37 PM
     
      Has Code

    I am looking at seperating Views from their respecting ViewModels without using any code behind. On obstacle in that endevour is the commanding framework. Currently, I am using the static approach:

    • That is, I have a static class MainCommands containing all static command properties that my application supports
    • In the constructor of each dialog I am binding to the respective command property to the corresponding method, like so:
    this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New,
                        (s, e) => this.New_CommandExecuted(s, e),
                        (s, e) => this.CanExecute_IfNoBatchRuns(s, e)));

    Now, I noticed that this can only be done in the code behind because the this.CommandBindings bit is otherwsie not available(?).

    I have also looked at other options such as the cool RelayCommand class that originated from Josh Smith's work. But with that class I am not sure how to seperate View and ViewModel without using codebehind. Plus, I need a solution that supports Short-Keys and InputGetsures when using a command in a GUI items that supports it (eg.: MenuItem).

    What is the current method to go about this? Are their any samples I could look at? Here is a summary list of the requirements I am after:

    • Seperate View and ViewModel without using code behind and using commands to expose ViewModel program logic functionality to the view
    • Support short keys and input gestures in GUI items such as the MenuItem like with the RoutedUICommand
    • Changed Type Dirkster9999 Thursday, March 15, 2012 4:41 PM
    •  

All Replies

  • Tuesday, March 06, 2012 6:37 PM
     
     

    >> I am looking at seperating Views from their respecting ViewModels without using any code behind.

    Well this is just opinion but I suggest you ask yourself "What am I accomplishing by doing this?" and "Are the benefits worth the costs?".  You may have already done this and if so I aplogize.   I know this does not answer your question and I dont have an answer, just a bit of adivse based on experience. 

  • Tuesday, March 06, 2012 7:19 PM
     
     

    Yes, you can connect a view to a viewmodel with no code behind.

    Expose the command from the viewmodel using relaycommand in the viewmodel.

    Bind to the command in xaml.

    Personally, I usually set the datacontext of the view to the viewmodel in the view constructor.

    You can altenatively instantiate each separately and set the datacontext extenally.  You then have created a complication for yourself because you have to dispose of your viewmodel somewhere.


    • Edited by Andy ONeill Tuesday, March 06, 2012 7:20 PM
    •  
  • Tuesday, March 06, 2012 9:34 PM
     
     
    I have not done it yet and I am not going to if there is no good solution - the benefit is that I am more flexible in choosing the view that I am using - right now I am using a home grown version but I would like to convert to the new version of Avalon Dock. I can already do it in the space of a few hours work but I am still wondering whether there is a better design approach to select a view in a flexible manner while maintaining a consistent design...in a nutshell: I am really asking for a solution not an opinion (because I got my own opinion too)

  • Tuesday, March 06, 2012 9:38 PM
     
     

    Hi Andy,

    I know I can do it with RelayCommand as I pointed out in the initial post - but what about input gestures and short keys? Is there a solution that includes them as well or is it either

    • code behind for the command binding and short keys

      OR

    • RelayCommand and no input gestures and short keys?
  • Tuesday, March 06, 2012 9:44 PM
     
     
    You can fire commands with gestures and you can bind commands.  It's not an issue.
  • Tuesday, March 06, 2012 10:50 PM
     
     

    Hi Andy,

    can you give me sample code to get me started? To me its an issue because I do not know how to do it :) otherwise I would not have asked. Thanks a lot for your patients :)

    I am looking for design that lets me use the commanding just like using the RoutedUICommand - that is - I can do something like <MenuItem Command="{Binding cmd:MyCommand}" /> and the MenuItem automatically locates the correct Header text and short keys.

    I can also use it with a button and bind the button text to the text of the RoutedUICommand etc... with RelayCommand I have no clue about how this can be implemented. Please give me more than: "yes sure you can do it"

  • Tuesday, March 06, 2012 11:01 PM
     
     

    Dirk;

      Don't hamstring yourself too much, You can bind commands in xaml is you include a reference to the class and you create a static instance withing the XAMLS resources section...  Then the command bindings can all be applied via the XAML editor which will use intellisense to help you.

    Everyone has their own opinions on MVVM, and mine are these: 1) You can have code in view code behind.  Try to limit it to GUI Related things etc.  Make it a goal to just do GUI stuff there.  You can even, if you want kick off commands but you miss out on WPF GUI features of binding commands in XAML instead.  When a command is bound in XAML then say on a button click it won't be enabled until the command is done!  All pretty much automated for you!

    I personally don't care for the relay command much but in that teaching they are used to boomerang a command back to view model.  Which is ok.  The viewmodel then is the brains for coordinating collections, telling the model when to get the data etc.  The View then just Binds to the collections in the Viewmodel.


    JP Cowboy Coders Unite!

  • Wednesday, March 07, 2012 9:20 AM
     
     

    This article demonstrates how to use relaycommand in much more detail than I'm likely to put in a post.

    http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    You are pretty much binding to a method exposed from the viewmodel, just doing it in a bit of an indirect way.

  • Wednesday, March 07, 2012 9:33 AM
     
     

    Hi Andy,

    I am aware of that article. Its great but it does not solve my problem (unless I am missing something). My problem is not with using the RelayCommand class. My problem is with using the RelayCommand and still being able to use short cuts, input gestures, and command text as described in my last post.

    I do not think that question is answered anywhere in Josh's article or am I missing something?

  • Wednesday, March 07, 2012 10:34 AM
     
     Answered Has Code

    Relaycommand just works just the same as a command.

    So you can make your command a resource and bind to that as a staticresource, attach gestures to that or you can bind it directly in the menuItem and set InputBindings.

                <Menu>
                    <MenuItem Name="New" Header="New Whatever" Command="a relay command">
                        <MenuItem.InputBindings>
                            <KeyBinding Key="N" Modifiers="Control" />
                        </MenuItem.InputBindings>
                   </MenuItem>
                </Menu>


    • Edited by Andy ONeill Wednesday, March 07, 2012 10:40 AM
    • Marked As Answer by Dirkster9999 Thursday, March 15, 2012 4:41 PM
    •  
  • Wednesday, March 07, 2012 1:46 PM
     
     
    Yes as Andy and I have both said, do the command binding in the XAML.... This gets you what you want.

    JP Cowboy Coders Unite!

  • Friday, March 09, 2012 1:34 AM
    Moderator
     
     

    Hi All,

    Thanks all for the excellent discussion in the MSDN forum.

    That's the exact same quesiton I had when I went through MVVM articles. If I didn't get it wrong, the InputBinding won't work for RelayCommand because it cannot bind to viewmodel.

    My solution is to use an attached property where you can specify the input gestures, then you can bind the attached property to the relaycommand.

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

  • Friday, March 09, 2012 1:17 PM
     
     

    Hi Everyone,

    thanks a lot for your input. Min's comment reflects at last what I was looking for. But now I am wondering why using an attached property if you have the source? I am thinking: Extend the RelayCommand class with an InputGesture and Text dependency property and see whether a menu item will pick it up automatically - if not - use the binding to do it.

    I'll get back here in a few days to let you guys know.

    Cheers Dirkster

  • Friday, March 09, 2012 1:27 PM
     
     Answered

    BTW there is absolutely nothing wrong with putting a few command calls in CODE BEHIND, so with that, you shouldn't really have a problem there.  You don't need any stinkin' relay command either, rather you can abstract ALL of your commands to a COMMAND folder.  In that folder implement your STATIC command classes, and just call them passing in any parms. you want.

    Sometimes I feel all of these tricks in MVVM cause a lot of frustration only because they are too complex for the simple things at hand.  If we look at what MSFT does with commands, they make them all publically accessable at start of program.  This means they are static and they are NOT in anyway tightly coupled.  This is the same thing you'd accomplish by moving some of these commands to their own folder.


    JP Cowboy Coders Unite!

    • Marked As Answer by Dirkster9999 Thursday, March 15, 2012 4:42 PM
    •  
  • Saturday, March 10, 2012 11:25 PM
     
     

    Hi Min,

    I think I got your solution wrong at first -because I thought you wanted to extend the RelayCommand with an attached property - but now I recognized that you want to extend the MenuItem (or any other GUI control) with an attached property and use that to kick of a command. Could you share some sample code on that?

    I got as far as playing with dependency properties in the RelayCommand class. And extending the class with a Text property was no problem, although, it not picked up automatically as with the RoutedUICommand when used in the MenuItem, it can still be bound and would thus, be OK. But I got nowhere near a useful implementation with the KeyBinding or display of it in the menu itself...

    Cheers Dirkster

  • Thursday, March 15, 2012 4:36 PM
     
     

    I've done some thinking and some tinkering and some more thinking and arrived at a similar conclusion. You either have to use RoutedUICommand with a minimal code behined or you can use RelayCommand implmented in the ViewModel. The later case requires to specify keyboard shortcusts and command text in the view - seperated from the ViewModel.

    So, both techniques have there drawbacks and putting a command with gestures and shortcuts in the viewmodel is not necessarily and advantage. Thanks for your patience.

  • Thursday, March 15, 2012 5:42 PM
     
     
    Excellent and thanks for feedback!

    JP Cowboy Coders Unite!

  • Saturday, May 18, 2013 5:56 PM
     
     

    The most efficient solution to is to use/develop the XAML -markup extension where you can solve this by delegating create instance of the “relay” to the XAML markup extension.

    Here are links: