Search code examples
c#wpfmvvmdata-binding

WPF MVVM Can i use model from view


I am still new to MVVM/WPF, in my control, i create a grid and when user clicks on a row, i want it to do something. Currently, i have in my code executes some code on the view. Is this okay? since the view need to access data from the model, or how can i fully separate the view and the model?

Currently, i have this...

// our View Window
public partial class MarketPriceView : UserControl
{
    public MarketPriceView()
    {
        InitializeComponent();      
    }

    private void OHLCChart_Click(object sender, RoutedEventArgs e)
    {
        // MarketPriceGrid is our model
        var cell = GridData.SelectedItem as MarketPriceGrid;
        string prod = cell.ProdCode;

        // do something with prod ...
    }
}

and my XAML i have a datagrid

<DataGrid x:Name="GridData" ItemsSource="{Binding MarketPriceGrid}">
  <DataGrid.ContextMenu>
    <ContextMenu>
      <MenuItem Header="OHLC Chart" Click="OHLCChart_Click"/>
     </ContextMenu>
    </DataGrid.ContextMenu>
    ...
</DataGrid>

Is this OK? Or how should i go about doing it without breaking the MVVM pattern?


Solution

  • The OHLCChart_Click event handler in the view should be replaced by an ICommand property of the view model that you bind to:

    <MenuItem Header="OHLC Chart" Command="{Binding ChartCommand"}/>
    

    Please refer to this blog post for more information about how to handle events in MVVM.

    You should also bind the SelectedItem property of the DataGrid to a source property of the view model:

    <DataGrid x:Name="GridData" ItemsSource="{Binding MarketPriceGrid}"
              SelectedItem="{Binding TheSelectedItem}">
    

    You will then have direct access to the currently selected item in the Execute method of the command in the view model:

    _clickCommand = new DelegateCommand<object>(
            (s) => { /* do something with this.TheSelectedItem */ }, //Execute
            (s) => true //CanExecute
            );
    

    This way, you move your application logic from the view to the view model where it belongs and can be tested and evolved in isolation without the presence of a view.

    Note that there are MVVM frameworks out there, such as for example Prism and MvvmLight, that provide implementations for ICommand and other MVVM related stuff to make your life easier.