【问题标题】:How to get RadioButtons to work like ComboBox in MVVM pattern?如何让 RadioButtons 像 MVVM 模式中的 ComboBox 一样工作?
【发布时间】:2010-11-03 23:41:39
【问题描述】:

在以下代码中,用户从 ComboBox 中选择一个客户,该客户的信息显示在框中。

现在我也想让 RadioButtons 使用相同的功能。我有 RadioButtons 来显示客户的 ObservableCollection,但我怎样才能让 IsChecked 工作,即 RadioButtons 的 SelectedItem 相当于什么

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>

视图模型:

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];
        }

    }
}

更新:

我也从 Thomas 那里尝试过,但它仍然无法将 IsChecked 与 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>

【问题讨论】:

    标签: wpf xaml radio-button


    【解决方案1】:

    ItemsControl 没有 SelectedItem 属性,您应该改用 ListBox

    此示例运行良好:

    <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
    

    【讨论】:

    • 我把这个想法融入到我上面的代码中并转发了,但似乎没有得到 IsChcked 和 IsSelected 之间的联系。
    • 这个解决方案非常完美,当我使用示例客户类对其进行原型制作时它也可以工作。您能否检查并确保输出窗口中没有显示任何绑定错误?
    猜你喜欢
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2019-07-05
    相关资源
    最近更新 更多