¿Cómo hacer que los botones de radio funcionen como ComboBox en el patrón MVVM?
-
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>
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