2016-02-14 3 views
3

я получил следующее событие:(ViewModel) DataContext возвращение нулевой

private void PlaceToken(object sender, RoutedEventArgs e) 
{ 
    ConnectFourViewModel currentViewModel = (ConnectFourViewModel)DataContext; 

    Button button = (Button)sender; 

    int currentColumn = Convert.ToInt32(button.Content); 

    int currentPlayer = currentViewModel.Board.CurrentPlayer; 
    currentViewModel.Board.PlaceToken(currentColumn, currentPlayer); 
} 

После следующих настройки:

public MainWindow() 
{ 
    var window = new Window(); 
    var grid = new Grid {}; 
    ConnectFourViewModel ViewModel = new ConnectFourViewModel(); 

    //Set up rows and cols 
    for(int i = 1; i<=7; i++) 
    { 
     var col = new ColumnDefinition(); 
     grid.ColumnDefinitions.Add(col); 
    } 
    for (int i = 1; i <= 7; i++) 
    { 
     var row = new RowDefinition(); 
     grid.RowDefinitions.Add(row); 
    } 

    //Set up tiles 
    foreach (var item in ViewModel.Board.AllTiles) 
    { 
     int index = ViewModel.Board.AllTiles.IndexOf(item); 

     string name = 
       "Col" + 
       Convert.ToString(item.Column) + 
       "_Row" + 
       Convert.ToString(item.Row); 

     Label currentTile = new Label{ Name = name}; 
     Grid.SetRow(currentTile, item.Row - 1); 
     Grid.SetColumn(currentTile, item.Column -1); 

     //Bind 
     var binding = new Binding(); 
     binding.Source = ViewModel.Board.AllTiles[index]; 
     binding.Path = new PropertyPath("Contents"); 

     currentTile.SetBinding(ContentProperty, binding); 

     //Add 
     grid.Children.Add(currentTile); 
    } 

    //Set up Buttons 
    for (int i = 1; i <= 7; i++) 
    { 
     Button currentButton = new Button { }; 

     //binding 
     var binding = new Binding(); 
     binding.Source = ViewModel.CurrentColumn; 

     currentButton.SetBinding(ContentProperty, binding); 

     //Set Column names, this has to be after the binding has been set. 
     currentButton.Content = i; 
     //events 
     currentButton.Click += new RoutedEventHandler(PlaceToken); 

     //add 
     Grid.SetColumn(currentButton, i - 1); 
     Grid.SetRow(currentButton, 7); 
     grid.Children.Add(currentButton); 
    } 

    window.Content = grid; 
    window.DataContext = ViewModel; 
    window.Show(); 
    InitializeComponent(); 
} 

Я ожидал линию ConnectFourViewModel currentViewModel = (ConnectFourViewModel) DataContext ; для установки currentViewModel для отражения информации, которую отключает пользовательский интерфейс. К сожалению, он возвращает null, и я не уверен, почему.

Это явно подчеркивает пробел в моем понимании темы, но, не зная, как ее решить, я мог бы использовать руку. Любая идея, где я пошла не так?

+2

Если у вас есть экземпляр ViewModel, созданный в вашем классе, зачем его использовать в DataContext? Вы можете просто использовать экземпляр. – Filip

+1

Также взгляните на [В конструкторе для окна WPF, что должно идти до InitializeComponent() и после чего?] (Http://stackoverflow.com/q/11479318/33499) – wimh

+1

Этот код отвратительный, 90% из которого должен быть в XAML. –

ответ

2

Вы не присвоили DataContext до ViewModel в любом месте. Предполагая, что вы хотите, чтобы ViewModel был ViewModel MainWindow, я предлагаю вам назначить его перед Initialize Component, как показано ниже. Поскольку он никогда не назначается, вы получаете нуль.

public MainWindow() 
{ 
    ConnectFourViewModel ViewModel = new ConnectFourViewModel(); 
    . . . 
    . . . 
    DataContext = ViewModel ; 
    InitializeComponent(); 
} 
+1

Спасибо, приятный краткий ответ. В качестве следующего вопроса: вы можете увидеть, где я установил window.DataContext, думая, что, поскольку мой интерфейс действительно находится в окне, DataContext должен работать в этом отдельном окне. Почему я устанавливаю контекст для главного окна, когда все в представленном в окне? – MGDavies

+1

Не мог обернуть голову вокруг вашего вопроса. Я предполагаю, что вы просите отзывы о качестве ?! В подходе, который вы приняли, много чего не так. Вы пишете код, например Winform, без использования XAML. 2. Вам не нужен другой объект окна для того, что вы делаете! Вы можете добавить все эти элементы управления в главное окно и назначить его с помощью модели представления. – CarbineCoder

Смежные вопросы