简体   繁体   English

如何以声明方式从ComboBox的内容设置RadioButton的IsChecked属性?

[英]How to set the IsChecked property of a RadioButton from the Contents of a ComboBox declaratively?

I have a comboBox which has the following items: a1, a2, a3, a4 and I have two RadioButtons r1 and r2. 我有一个具有以下项目的comboBox:a1,a2,a3,a4,并且我有两个RadioButtons r1和r2。 This is what I want to accomplish: if the user selects item a2 from the combobox the IsChecked property of r1 should be set to true. 这就是我要完成的工作:如果用户从组合框中选择项a2,则r1的IsChecked属性应设置为true。 If the user selects either item a3 or a4 from the combobox the IsChecked propertyr of r2 should be set to true. 如果用户从组合框中选择项目a3或a4,则r2的IsChecked属性应设置为true。 I would like to accomplish this declaratively; 我想声明式地完成此操作; ie without using a Converter. 即不使用转换器。 Here is my Code and thanks in advance: 这是我的代码,在此先感谢:

<Window x:Class="BMSystem.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style x:Key="myRadioActivator1">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Content, ElementName=comboBox1}" Value="R2">
                    <Setter Property="RadioButton.IsChecked" Value="True"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <Style x:Key="myRadioActivator2">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Content, ElementName=comboBox1}" Value="R3">
                    <Setter Property="RadioButton.IsChecked" Value="True"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Content, ElementName=comboBox1}" Value="R4">
                    <Setter Property="RadioButton.IsChecked" Value="True"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" SelectionChanged="comboBox1_SelectionChanged">
            <ComboBoxItem>R1</ComboBoxItem>
            <ComboBoxItem>R2</ComboBoxItem>
            <ComboBoxItem>R3</ComboBoxItem>
            <ComboBoxItem>R4</ComboBoxItem>
        </ComboBox>
        <RadioButton Height="16" HorizontalAlignment="Left" Margin="10,43,0,0" Name="r1" VerticalAlignment="Top" Width="120" Style="{StaticResource myRadioActivator1}">
        </RadioButton>
        <RadioButton Height="16" HorizontalAlignment="Left" Margin="10,69,0,0" Name="r2" VerticalAlignment="Top" Width="120" Style="{StaticResource myRadioActivator2}">
        </RadioButton>
    </Grid>
</Window>

I think your goal of doing this without a converter is good, but your goal of doing it entirely declaratively is questionable. 我认为您的目标无需转换器就可以实现,但是您完全声明性地执行此目标是有疑问的。 I'd add an IsChecked property to the view model of the ComboBox 's items and bind to it. 我将IsChecked属性添加到ComboBox的项目的视图模型中并绑定到它。 Putting the decision-making process that underlies the setting of that property into the view seems, to me, to be muddying up the separation of concerns. 在我看来,将构成该财产设置基础的决策过程纳入视野之内,似乎正在使关注点分离变得更加混乱。

Man... those are some weird requirements! 伙计...这些是一些奇怪的要求!

Here is one solution: 这是一种解决方案:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
  <Page.Resources> 
    <XmlDataProvider x:Key="CBOptions">
      <x:XData>
        <Data xmlns="">
          <Option Name="R1" />
          <Option Name="R2" IsR1Checked="True" />
          <Option Name="R3" IsR2Checked="True" />
          <Option Name="R4" IsR2Checked="True" />
        </Data>
      </x:XData>
    </XmlDataProvider>
    <DataTemplate x:Key="CBItemTemplate">
      <TextBlock Text="{Binding XPath=@Name}" />
    </DataTemplate>
  </Page.Resources> 
  <Grid DataContext="{Binding ElementName=comboBox1, Path=SelectedItem}"> 
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="comboBox1" 
        VerticalAlignment="Top" Width="120" IsSynchronizedWithCurrentItem="True"
        ItemsSource="{Binding Source={StaticResource CBOptions}, XPath=Data/Option}"
        ItemTemplate="{StaticResource CBItemTemplate}" />
    <RadioButton Height="16" HorizontalAlignment="Left" Margin="10,43,0,0" 
        Name="r1" VerticalAlignment="Top" Width="120" GroupName="R1" 
        IsChecked="{Binding XPath=@IsR1Checked}" />
    <RadioButton Height="16" HorizontalAlignment="Left" Margin="10,69,0,0" 
        Name="r2" VerticalAlignment="Top" Width="120" GroupName="R2" 
        IsChecked="{Binding XPath=@IsR2Checked}" />
  </Grid> 
</Page> 

You could do it by moving everything into a DataTemplate and using Trigger s there. 您可以通过将所有内容移至DataTemplate并在其中使用Trigger I would probably consider Robert's suggestion that this be fixed in a ViewModel or some other bound object because it sounds more like it might be more business logic than just UI. 我可能会考虑罗伯特的建议,将其固定在ViewModel或其他绑定的对象中,因为听起来更像是更多的业务逻辑,而不仅仅是UI。 That said: 说:

<ContentControl Content="{Binding}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" SelectionChanged="comboBox1_SelectionChanged"
                          SelectedValuePath="Content">
                    <ComboBoxItem>R1</ComboBoxItem>
                    <ComboBoxItem>R2</ComboBoxItem>
                    <ComboBoxItem>R3</ComboBoxItem>
                    <ComboBoxItem>R4</ComboBoxItem>
                </ComboBox>
                <RadioButton Height="16" HorizontalAlignment="Left" Margin="10,43,0,0" Name="r1" VerticalAlignment="Top" Width="120" >
                </RadioButton>
                <RadioButton Height="16" HorizontalAlignment="Left" Margin="10,69,0,0" Name="r2" VerticalAlignment="Top" Width="120" >
                </RadioButton>
            </Grid>
            <DataTemplate.Triggers>
                <Trigger SourceName="comboBox1" Property="SelectedValue" Value="R2">
                    <Setter TargetName="r1" Property="RadioButton.IsChecked" Value="True"/>
                </Trigger>
                <Trigger SourceName="comboBox1" Property="SelectedValue" Value="R3">
                    <Setter TargetName="r2" Property="RadioButton.IsChecked" Value="True"/>
                </Trigger>
                <Trigger SourceName="comboBox1" Property="SelectedValue" Value="R4">
                    <Setter TargetName="r2" Property="RadioButton.IsChecked" Value="True"/>
                </Trigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM