2016-12-15 7 views
0

У меня есть приложение, использующее WPFmah metro, где у меня есть tab controlУстановка DataContext из ViewModel не в конструкторе

<Controls:MetroAnimatedTabControl Grid.Column="3" Grid.Row="1" SelectedIndex="{Binding SelectedTabIndex,Mode=TwoWay}"> 
     <TabItem Header="Manual Control"> 
      <view:ManualControlView DataContext="{Binding ManualControlViewModel}"/> 
     </TabItem> 
     <TabItem Header="Set up"> 
      <view:SetupView DataContext="{Binding SetupViewModel}"/> 
     </TabItem> 
    </Controls:MetroAnimatedTabControl> 

Я устанавливающее datacontext в TabItem. Я создаю TcpCllient и передаю эту ссылку каждому ViewModel. Когда я делаю это в конструкторе, все работает нормально.

public MainViewModel() 
    { 
     _client = new TcpClient(IP_ADDRESS, PORT); 
     _client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 
     _master = ModbusIpMaster.CreateIp(_client); 

     ManualControlViewModel = new ManualControlViewModel(_master); 
     SetupViewModel = new SetupViewModel(_master); 

    } 

Однако, я не хочу, чтобы создать TcpClient в конструкторе. Вместо этого я хочу создать его, когда я нажму кнопку «Подключиться» в своем окне. Однако, когда я нажимаю кнопку «Подключиться» для выполнения метода OnConnect, для этого мои представления не устанавливаются в datacontext.

private void OnConnect(object obj) 
    { 
     _client = new TcpClient(IP_ADDRESS, PORT); 
     _client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 
     _master = ModbusIpMaster.CreateIp(_client); 
     Connected = _client.Connected; 

     ManualControlViewModel = new ManualControlViewModel(_master); 
     SetupViewModel = new SetupViewModel(_master);   

     StartReadingInfo(); 
    } 

Можно ли это осуществить?

+0

Смотрите мой ответ здесь http://stackoverflow.com/questions/5650812/how-do-i-bind-a-tabcontrol-to-a-collection-of-viewmodels/5651542#5651542, который показывает, как для работы с TabControl с использованием MVVM. Ваша кнопка должна быть привязана к ICommand в вашей модели просмотра (в зависимости от того, что подходит), и *, который * должен обновлять другие модели представлений, уже привязанные к пользовательскому интерфейсу. Ваши свойства также должны реализовать INotifyPropertyChanged, чтобы сообщить пользовательскому интерфейсу, что значения свойств ... изменены. – Will

ответ

1

При обновлении свойств ViewModel вы должны уведомить Control о том, что свойства изменены.

 public class ViewModel : INotifyPropertyChanged 
     { 

      public SetupViewModel SetupViewModel 
      { 
       get { return m_SetupViewModel; } 
       set 
       { 
        m_SetupViewModel = value; 
        OnPropertyChanged(); 
       } 
      } 

      public ManualControlViewModel ManualControlViewModel 
      { 
       get { return m_ManualControlViewModel; } 
       set 
       { 
        m_ManualControlViewModel = value; 
        OnPropertyChanged(); 
       } 
      } 

      public event PropertyChangedEventHandler PropertyChanged; 

      private void OnConnect(object obj) 
      { 
       _client = new TcpClient(IP_ADDRESS, PORT); 
       _client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 
       _master = ModbusIpMaster.CreateIp(_client); 
       Connected = _client.Connected; 

       ManualControlViewModel = new ManualControlViewModel(_master); 
       SetupViewModel = new SetupViewModel(_master); 

       StartReadingInfo(); 
      } 

      private void OnPropertyChanged([CallerMemberName] string PropertyName = "") 
      { 
       var handler = PropertyChanged; 
       if (handler != null) handler(this, new PropertyChangedEventArgs(PropertyName)); 
      } 

      private ManualControlViewModel m_ManualControlViewModel; 
      private SetupViewModel m_SetupViewModel; 
     }