Comment faire en sorte que les boutons radio fonctionnent comme ComboBox dans un modèle MVVM?
-
06-07-2019 - |
Question
Dans le code suivant, l'utilisateur sélectionne un client dans la zone de liste déroulante et les informations de ce client sont affichées dans la zone.
Maintenant, je souhaite également que RadioButtons fonctionne avec les mêmes fonctionnalités. J'ai les boutons radio pour afficher la collection observable de clients, mais comment puis-je faire fonctionner IsChecked , c'est-à-dire quel est l'équivalent de SelectedItem
pour 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>
Modèle de vue:
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];
}
}
}
Mise à jour:
J'ai aussi essayé ça de Thomas, mais ça ne connecte toujours pas IsChecked avec 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>
La solution
ItemsControl n'a pas de propriété SelectedItem, vous devez plutôt utiliser un contrôle ListBox
Cet exemple fonctionne 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow