In MVVM is it acceptable to access the ViewModel in the view's code behind?

c#, datacontext, mvvm, viewmodel, wpf

Solution

If the question is just about how to access the ViewModel from code behind, you could simply cast the DataContext to the proper type:

var viewModel = (MyViewModel)DataContext;

foreach (var currency in viewModel.Currencies)
{
    ...
}

If this is acceptable or not is a matter of taste. I do not see any fundamental difference in accessing the view model by bindings in the view's XAML or by a piece of code-behind.

Problem

IN an MVVM pattern is it acceptable or even possible to access ViewModel properties in the views code behind? I have an observable collection which is populated in the ViewModel. I need to use it in the view to bind to an endless ticker with a linked list. i.e. ``` private LinkedList<Border> tickerForex = new LinkedList<Border>(); public ForexBuy() { InitializeComponent(); DataContext = new ForexViewModel(); } private void InitializeForexTicker() { CanvasForexBuyTicker.Children.Clear(); foreach (var currency in DataContext.Currencies) //Is this possible/allowable??? { AddTickerItem(currency); } CanvasForexBuyTicker.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate { var node = tickerForex.First; while (node != null) { if (node.Previous != null) { Canvas.SetLeft(node.Value, Canvas.GetLeft(node.Previous.Value) + node.Previous.Value.ActualWidth + gap); } else { Canvas.SetLeft(node.Value, CanvasForexBuyTicker.Width + gap); } node = node.Next; } return null; }), null); } void AddTickerItem(Currency currency) { Border border = new Border(); border.Background = new SolidColorBrush(Color.FromArgb(255, 0, 99, 99)); if (currency.IsUpward == 0) { border.Background = new SolidColorBrush(Color.FromArgb(255, 255, 153, 0)); } border.BorderThickness = new Thickness(3); border.BorderBrush = new SolidColorBrush(Colors.White); border.CornerRadius = new CornerRadius(10); border.Width = Double.NaN; border.Height = 35; UIHelper.CanvasAutoSize canvas = new UIHelper.CanvasAutoSize(); canvas.Background = Brushes.Green; canvas.Tag = currency; canvas.Height = Double.NaN; TextBlock tb = new TextBlock { Text = currency.Code + " " + currency.Sell + " ", FontSize = 22, FontWeight = FontWeights.Bold, Foreground = Brushes.Black }; tb.SetValue(Canvas.LeftProperty, 8d); tb.SetValue(Canvas.TopProperty, 2d); canvas.Children.Add(tb); tb.TouchDown += TouchTickerItem; border.Child = canvas; CanvasForexBuyTicker.Children.Add(border); Canvas.SetTop(CanvasForexBuyTicker, 3); Canvas.SetLeft(CanvasForexBuyTicker, 0); tickerForex.AddLast(border); } ``` I'm a little lost as to whether the dispatcher should fire from the ViewModel or whether to use it in the views code behind.

Original source