Search code examples
c#wpfdata-binding

WPF - Bind commands to ListBox items?


as the title suggests, I'm

My MainWindow.xaml has MainWindowViewModel.cs as its DataContext, and within this ViewModel is an ObservableCollection.
In the .xaml file, I added a ListBox as follows:

<ListBox ItemsSource="{Binding RoleTypes}">
    <ListBox.ItemTemplate>
       <DataTemplate>
          <RadioButton Content="{Binding}" 
             GroupName="ClientRole"
             Command="{Binding SetSelectedRoleCommand, Mode=OneWay}" 
             CommandParameter="{Binding Content, 
             RelativeSource={RelativeSource Self}}">
          </RadioButton>
       </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

The issue is that I need to bind my Content variable to the value of my Observable collection, but I also need to bind to my command, which is accessible from the Window.DataContext. Trying to bind my command to the Window.DataContext will work, but now, Content will bind to the ViewModel class itself.

Is there a way I can both have my radio buttons bind to the content of the ObservableCollection while being able to call my command with the correct parameters?

Thanks a lot!


Solution

  • You can bind your command to DataContext either using RelativeSource

    <ListBox ItemsSource="{Binding RoleTypes}">
        <ListBox.ItemTemplate>
           <DataTemplate>
              <RadioButton Content="{Binding}" 
                 GroupName="ClientRole"
                 Command="{Binding DataContext.SetSelectedRoleCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" 
                 CommandParameter="{Binding}">
              </RadioButton>
           </DataTemplate>
       </ListBox.ItemTemplate>
    </ListBox>
    

    or you can set name to ListBox or a window itself and bind using ElementName:

    <ListBox x:Name="list" ItemsSource="{Binding RoleTypes}">
        <ListBox.ItemTemplate>
           <DataTemplate>
              <RadioButton Content="{Binding}" 
                 GroupName="ClientRole"
                 Command="{Binding DataContext.SetSelectedRoleCommand, ElementName=list}" 
                 CommandParameter="{Binding}">
              </RadioButton>
           </DataTemplate>
       </ListBox.ItemTemplate>
    </ListBox>
    

    BTW, why do you need so complicated binding for CommandParameter? It seems that it should be simply {Binding}.