views:

280

answers:

3

I have a comboBox which has the following items: a1, a2, a3, a4 and I have two RadioButtons r1 and 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. If the user selects either item a3 or a4 from the combobox the IsChecked propertyr of r2 should be set to true. I would like to accomplish this declaratively; i.e. 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>
+1  A: 

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. 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.

Robert Rossney
A: 

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"&gt; 
  <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> 
Dr. WPF
A: 

You could do it by moving everything into a DataTemplate and using Triggers there. 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. 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>
John Bowen