Search code examples
c#wpfmvvmdatacontextitemssource

How to access data from ViewModel in ItemsSource tag


I'm making TabControl that can change dynamically using ItemsSource tag. I want to know the way to access ViewModel data in ItemsSource tag.

I searched through the Internet. but I couldn't find the answer.

CODE

public class ViewModel
{
      // this will be used in ItemsSource
      private ObservableCollection<ActiveButton> _allExecuteButtonInfos = new ObservableCollection<ActiveButton>();

      public ObservableCollection<ActiveButton> AllExecuteButtonInfos
      {
        get { return _allExecuteButtonInfos; }
        set {
            _allExecuteButtonInfos = value;
            OnPropertyChanged();
        }
      }

      // I want to get this data in ItemsSource
      private List<string> _boardNameList = new List<string>();

      public string BoardNameList
      {
          get { return _boardNameList; }
          set {
              _boardNameList = value;
              OnPropertyChanged();
          }
      }
}

XAML

<Grid>
   <TabControl Background="#FF292929" ItemsSource="{Binding AllExecuteButtonInfos}">                     
          <TabControl.ContentTemplate>
              <DataTemplate>
                  <ScrollViewer Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto">
                      <Grid VerticalAlignment="Stretch" Margin="0,0,0,0" >
                          <ComboBox Width="334" Margin="0,0,0,0" Grid.Column="1" Grid.Row="1" Height="22" VerticalAlignment="Top" 
                                   <!-- I want to get data from ViewModel not in ItemsSource(AllExecuteButtonInfos) -->
                                   <!-- eg) VM:BoardNameList, ViewModel.BoardNameList etc -->
                                    ItemsSource="{Binding BoardNameList, Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}"  
                                    SelectedItem="{Binding SelectedBoard, Mode=TwoWay}"/>
                      </Grid>
                  </ScrollViewer>
               </DataTemplate>
          </TabControl.ContentTemplate>
    </TabControl>
</Grid>

I hope I can find the answer.

Thank you.


Solution

  • You could bind to the DataContext, i.e. the view model, of the parent TabControl using a RelativeSource:

        <ComboBox ... 
            ItemsSource="{Binding DataContext.BoardNameList, RelativeSource={RelativeSource AncestorType=TabControl}}" />
    

    Note that it's pointless to set the Mode of an ItemsSource binding to TwoWay since the control never sets the property. It's also meaningless to set the UpdateSourceTrigger to PropertyChanged in this case for the same reason.