2012-12-06 36 views
2

在MVVM模式中,是否可以接受甚至可能在後面的視圖代碼中訪問ViewModel屬性?在視圖代碼後面的DataContext值

我有一個可觀察的集合在ViewModel中填充。我需要在視圖中使用它來綁定一個帶有鏈表的無限動態鏈接器。即

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); 
    } 

我有點失落,調度員應該從ViewModel觸發還是在視圖代碼中使用它。

+0

爲什麼不能直接綁定到'ViewModel'中的列表? –

+0

看不出有什麼幫助。 'CanvasForexBuyTicker'需要附加調度程序,ViewModel不會(不應該)瞭解畫布。 –

回答

8

如果問題是隻是如何從代碼中訪問視圖模型的背後,你可以簡單地在DataContext轉換爲正確的類型:

var viewModel = (MyViewModel)DataContext; 

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

如果這是可以接受與否是一個口味問題。我沒有看到通過視圖的XAML中的綁定或一段代碼隱藏訪問視圖模型的根本區別。

0

簡要回答:沒有。

你不應該在後面的代碼中放置商業或模型特定的代碼。只有VIEW特定的代碼應放在代碼後面。

你爲什麼要宣佈List<Border>。聽起來很奇怪。你究竟想要做什麼?

+0

這是列表邊框,因爲代碼中的項目是在邊框中設置的畫布中設置的TextBlocks。我知道你不應該把商業邏輯放在代碼背後。這樣的調度員不會成爲視圖邏輯的一部分嗎?例如因爲它是無止境的,我必須繼續檢查最後一個是否進入視圖並再次追加第一個節點。 –

+0

@JohnSourcer這是'ItemsControl'的意思。我試圖讓我的頭,以瞭解你在這裏做什麼,但我不能 –

+0

感謝您的期待。我已經編輯了上面的代碼來澄清。 –