Comment faire en sorte que les boutons radio fonctionnent comme ComboBox dans un modèle MVVM?

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

  •  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>
Était-ce utile?

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
scroll top