如何在XAML中绑定到单选按钮选定属性

本文关键字:单选按钮 属性 绑定 XAML | 更新日期: 2023-09-27 18:17:02

使用visual studio 2015社区,以及。net 4.5

我有一个特定于我的应用程序的用户的动态单选按钮列表。当用户使用web服务进行身份验证时,该按钮列表是动态创建的。该列表存储在ObservableCollection中。我已经将它绑定到XAML,它正确地呈现,并在选择后正确地存储isSelected。

我想做的是当用户选择服务类型(单击单选按钮)时有一个事件触发器。我读过很多例子,但他们硬编码单选按钮,但在我的情况下,我需要的按钮是动态的。

如何将XAML中的按钮单击绑定到ViewModel?

ServiceCost.cs

public class ServiceCost
{
    public long pst_id { get; set; }
    public string pst_description_short { get; set; }
    public decimal pst_cost { get; set; }
    private bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set{if (value != _isSelected) { _isSelected = value; } }
    }
    public string DescriptionPrice
    {
        get
        {
            return string.Format(Strings.ServiceCost_DescriptionPrice, this.pst_description_short, pst_cost.ToString());
        } 
    }
 ...
xaml:

  ...
  <GroupBox
      Grid.Row="1"
      Grid.ColumnSpan="2"
      Grid.Column="2"
      FontWeight="Bold"
      Header="Select Service Type"
      Margin="0,7,0,0"
      Padding="2">
        <ItemsControl FontWeight="Normal" ItemsSource="{Binding Path=ServiceTypes}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <RadioButton
                          Content="{Binding Path=DescriptionPrice}"
                          IsChecked="{Binding Path=IsSelected}"
                          GroupName="ServiceType"
                          Margin="2,3.5"
                          />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </GroupBox>
    ...

ViewModel:

    ...
    private ObservableCollection<ServiceCost> _serviceTypes;
    public ObservableCollection<ServiceCost> ServiceTypes
    {
        get { return _serviceTypes; }
        set
        {
            if (_serviceTypes != value)
            {
                _serviceTypes = value;
                DynamicOnPropertyChanged();
            }
        }
    }
    ...

如何在XAML中绑定到单选按钮选定属性

如果我正确理解您的问题,您希望仅在XAML中执行此操作。如果是这样,使用EventTrigger是可行的方法。

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <RadioButton Margin="2,3.5"
                     Content="{Binding Path=DescriptionPrice}"
                     GroupName="ServiceType"
                     IsChecked="{Binding Path=IsSelected}">
            <RadioButton.Triggers>
                <EventTrigger RoutedEvent="ToggleButton.Checked">
                </EventTrigger>
            </RadioButton.Triggers>
        </RadioButton>
    </DataTemplate>
</ItemsControl.ItemTemplate>

注意,RadioButton的Checked事件可以通过它的基类ToggleButton访问。如果您需要在此事件上调用代码,您可以尝试此技术。

我遇到的问题是在单选按钮单击后访问viewModel。经过大量的搜索,我发现ListBox是一种包装单选按钮的方式,它有一个selectedItem,然后我可以将ListBox的selectedItem绑定到我的ViewModel并访问变量。我不知道这是不是让它工作的最好方法,但它确实对我有用。

ServiceCost.cs = unchanged.

xaml:

...
    <GroupBox
      Grid.Row="1"
      Grid.ColumnSpan="2"
      Grid.Column="2"
      FontWeight="Bold"
      Header="Select Service Type"
      Margin="0,7,0,0"
      Padding="2" >
        <ListBox  Margin="0,10,0,10" BorderThickness="0" Background="Transparent"
            ItemsSource="{Binding ServiceCosts}"
            SelectedItem="{Binding SelectedServiceCost}" >
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <ContentPresenter/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <RadioButton Content="{Binding DescriptionPrice}"
                       IsChecked="{Binding Path=IsSelected, Mode=TwoWay,  RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Margin="0,5,0,5"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </GroupBox>
    ...

viewModel:

    ...
    private ObservableCollection<ServiceCost> _serviceCosts;
    public ObservableCollection<ServiceCost> ServiceCosts
    {
        get { return _serviceCosts; }
        set { if (_serviceCosts != value){_serviceCosts = value;    DynamicOnPropertyChanged();}}
    }
    private ServiceCost _selectedServiceCost;
    public ServiceCost SelectedServiceCost
    {
        get { return _selectedServiceCost; }
        set
        { 
            if (_selectedServiceCost != value)
            {
                // This is what I needed access to:  do something here!.
                _selectedServiceCost = value;
                DynamicOnPropertyChanged(); 
            }
        }
    }
    ...