¿Cómo hacer que los botones de radio funcionen como ComboBox en el patrón MVVM?

StackOverflow https://stackoverflow.com/questions/1012410

  •  06-07-2019
  •  | 
  •  

Pregunta

En el siguiente código, el usuario selecciona un cliente del ComboBox y la información de ese cliente se muestra en el cuadro.

Ahora también quiero que RadioButtons funcione con la misma funcionalidad. Tengo los RadioButtons para mostrar la Colección Observable de Clientes, pero ¿cómo puedo hacer que el IsChecked funcione, es decir, cuál es el equivalente de SelectedItem para RadioButtons ?

XAML:

<Window.Resources>

    <DataTemplate x:Key="CustomerShowTemplate">
        <Border CornerRadius="5" 
                Background="#eee" 
                Padding="5" 
                HorizontalAlignment="Left">
            <StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock FontSize="14" FontWeight="Bold" Text="{Binding FirstName}"/>
                    <TextBlock Text=" "/>
                    <TextBlock FontSize="14" FontWeight="Bold" Text="{Binding LastName}"/>
                </StackPanel>
                <TextBlock Text="{Binding Path=HireDate, 
                    StringFormat='Hired on {0:MMM dd, yyyy}'}"/>
            </StackPanel>
        </Border>
    </DataTemplate>

    <DataTemplate x:Key="CustomerComboBoxTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding FirstName}"/>
            <TextBlock Text=" "/>
            <TextBlock Text="{Binding LastName}"/>
        </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="CustomerRadioButtonTemplate">
        <RadioButton GroupName="CustomerRadioButtonGroup" 
            IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}">
            <TextBlock Text="{Binding LastName}"/>
        </RadioButton>
    </DataTemplate>

</Window.Resources>

<DockPanel LastChildFill="False" Margin="10">

    <ContentControl 
        DockPanel.Dock="Top"
        Margin="0 0 0 10"
        Content="{Binding SelectedCustomer}" 
        ContentTemplate="{StaticResource CustomerShowTemplate}"/>

    <StackPanel 
        DockPanel.Dock="Top"
        Margin="0 0 0 10">

        <ComboBox 
            ItemsSource="{Binding Customers}"
            ItemTemplate="{StaticResource CustomerComboBoxTemplate}"
            Margin="20"
            HorizontalAlignment="Left"
            SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/>

        <ListBox 
            ItemsSource="{Binding Customers}"
            ItemTemplate="{StaticResource CustomerRadioButtonTemplate}" 
            SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/>


        <TextBlock Text="{Binding Customers.Count}"/>


        <Button Content="Add Customer" Command="{Binding AddCustomerCommand}"/>


    </StackPanel>

</DockPanel>

ViewModel:

using System;
using System.Collections.ObjectModel;
using TestSelectedItem234.Models;

namespace TestSelectedItem234.ViewModels
{
    public class MainViewModel : ViewModelBase
    {

        #region ViewModelProperty: Customers
        private ObservableCollection<Customer> _customers = new ObservableCollection<Customer>();
        public ObservableCollection<Customer> Customers
        {
            get
            {
                return _customers;
            }

            set
            {
                _customers = value;
                OnPropertyChanged("Customers");
            }
        }
        #endregion

        #region ViewModelProperty: SelectedCustomer
        private Customer _selectedCustomer;
        public Customer SelectedCustomer
        {
            get
            {
                return _selectedCustomer;
            }

            set
            {
                _selectedCustomer = value;
                OnPropertyChanged("SelectedCustomer");
            }
        }
        #endregion

        #region ViewModelProperty: CustomerIsSelected
        private bool _customerIsSelected;
        public bool CustomerIsSelected
        {
            get
            {
                return _customerIsSelected;
            }

            set
            {
                _customerIsSelected = value;
                OnPropertyChanged("CustomerIsSelected");
            }
        }
        #endregion

        public MainViewModel()
        {
            LoadCustomers();

            CustomerIsSelected = false;
        }

        private void LoadCustomers()
        {
            _customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", HireDate = DateTime.Parse("2007-12-31") });
            _customers.Add(new Customer { FirstName = "Jack", LastName = "Taylor", HireDate = DateTime.Parse("2005-12-31") });
            _customers.Add(new Customer { FirstName = "Jane", LastName = "Smith", HireDate = DateTime.Parse("2005-06-30") });
            _customers.Add(new Customer { FirstName = "Alice", LastName = "Jones", HireDate = DateTime.Parse("2005-08-23") });
            _customers.Add(new Customer { FirstName = "Mary", LastName = "Ashton", HireDate = DateTime.Parse("2005-12-22") });
            _customers.Add(new Customer { FirstName = "Joe", LastName = "Jones", HireDate = DateTime.Parse("2005-11-22") });
            _customers.Add(new Customer { FirstName = "Henry", LastName = "Smith", HireDate = DateTime.Parse("2005-12-11") });
            _customers.Add(new Customer { FirstName = "Allison", LastName = "Rodrigez", HireDate = DateTime.Parse("2004-12-14") });
            _customers.Add(new Customer { FirstName = "Angela", LastName = "Thompson", HireDate = DateTime.Parse("2003-03-14") });
            _customers.Add(new Customer { FirstName = "Shawna", LastName = "Quaker", HireDate = DateTime.Parse("2005-12-14") });

            SelectedCustomer = _customers[0];
        }

    }
}

Actualización:

También probé esto de Thomas, pero aún no conecta IsChecked con IsSelected:

<ListBox ItemsSource="{Binding Customers}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <RadioButton Content="{Binding FirstName}" IsChecked="{Binding IsSelected, RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
¿Fue útil?

Solución

ItemsControl no tiene una propiedad SelectedItem, debería usar un ListBox en su lugar

Esta muestra funciona bien:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <Page.Resources>
    <x:Array x:Key="stringList" Type="sys:String">
      <sys:String>Hello</sys:String>
      <sys:String>World</sys:String>
      <sys:String>!</sys:String>
    </x:Array>
  </Page.Resources>
  <Grid>
    <ListBox ItemsSource="{StaticResource stringList}">
      <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <RadioButton Content="{Binding}" IsChecked="{Binding IsSelected, RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </ListBox.ItemContainerStyle>
    </ListBox>
  </Grid>
</P
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top