none
How to set selected item in ListBox containing RadioButtons? RRS feed

  • Question

  • I have a tabcontrol that is bound to a view model which contains a list of other view models for the tabs. The content in each tab can vary so I have different data templates and a template selector to choose depending on the selected tab. All of this works just fine.

    In some of the data templates I have a listbox that is bound to a list of objects. The objects are displayed as RadioButtons on the listbox.

    <Style x:Key="radioListBox1" TargetType="{x:Type ListBox}">
       <Setter Property="BorderThickness" Value="0" />
       <Setter Property="Margin" Value="2" />
       <Setter Property="DisplayMemberPath" Value="Name" />
       <Setter Property="SelectedValuePath" Value="Value" />
       <Setter Property="Background" Value="{x:Null}" />
       <Setter Property="VerticalContentAlignment" Value="Center"/>
       <Setter Property="VerticalAlignment" Value="Center"/>
       <Setter Property="ItemContainerStyle">
          <Setter.Value>
             <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                   <Setter.Value>
                      <ControlTemplate TargetType="{x:Type ListBoxItem}">
                         <Grid Background="Transparent">
                            <RadioButton Focusable="False" IsHitTestVisible="False" IsChecked="{TemplateBinding IsSelected}" Margin="0,0,15,0">
                               <ContentPresenter />
                            </RadioButton>
                         </Grid>
                      </ControlTemplate>
                   </Setter.Value>
                </Setter>
             </Style>
          </Setter.Value>
       </Setter>
    </Style>
    


    And the listbox in the data template is as follows:

    <TextBlock Text="RadioButton List:" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" Margin="0,0,10,0" VerticalAlignment="Center" />
    <ListBox x:Name="lstSpeeds" 
             Grid.Column="1" 
             Grid.Row="1" 
             ItemsSource="{Binding MasteringSpeeds}"
             IsSynchronizedWithCurrentItem="True" 
             SelectedItem="{Binding SelectedMasteringSpeed}"
             Style="{StaticResource radioListBox1}" 
             ScrollViewer.HorizontalScrollBarVisibility="Disabled"
             Background="Transparent"> 
       <ListBox.ItemsPanel>
          <ItemsPanelTemplate>
             <WrapPanel />
          </ItemsPanelTemplate>
       </ListBox.ItemsPanel>
    </ListBox>


    In the view model, I have the following:

    public ObservableCollection<_T_SPEED_ITEM> MasteringSpeeds
    {
       get
       {
          return _masteringSpeeds;
       }
    }
    public _T_SPEED_ITEM SelectedItem
    {
       get { return selectedMasteringSpeed; }
       set
       {
          selectedMasteringSpeed = value;
          OnPropertyChanged();
       }
    }
    

    When the window is displayed, all tabs and their content appear ok. The only problem I have is that I cannot select the default radiobutton. I want the first button on the list to be selected by default. In the constructor I check to see if the of items list contains any items and if so, then I select the fist one.

    public TabViewModelBase(ITabData page)
    {
       _masteringSpeeds = new ObservableCollection<ISpeedItem>();
    
       foreach (ISpeedItem spdItem in page.Speeds)
       {
          _masteringSpeeds.Add(item);
       }
    
       if (_masteringSpeeds.Count > 0)
          _selectedMasteringSpeed = _masteringSpeeds[0];
    }
    

    The tab view models are created first and passed to the tabcontrol view model. I can see when the code selects the first radiobutton (when there is one). But this happens when the view model is created, before it is bound to a tab. Once bountd, none of the radio buttons are selected when the content is displayed in the tab. I can select a radiobutton myself and all looks ok.

    Originally I thought of selecting the first radiobutton via the window's code-behind. However, since I'm using a content template selector, the listbox is not included on some of the data templates so I cannot hard-code it. I'm not familiar on how to find the listbox control.

    Friday, October 11, 2019 12:18 AM

Answers

  •     
    Hi   LeoAyala,

    >>Originally I thought of selecting the first radiobutton via the window's code-behind. However, since I'm using a content template selector, the listbox is not included on some of the data templates so I cannot hard-code it. I'm not familiar on how to find the listbox control.
    Daniel Zhang 

    I suggest you can use the VisualTreeHelper  :  Provides utility methods that perform common tasks involving nodes in a visual tree.

    Fro your reference:WPF find element with VisualTreeHelper vertical and horizontal


    Best regards

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by LeoAyala Saturday, October 12, 2019 3:01 PM
    Friday, October 11, 2019 9:04 AM
    Moderator