Home > front end >  Display a StackPanel only if one of two options are selected in a radio button
Display a StackPanel only if one of two options are selected in a radio button

Time:12-13

I have a WPF application and one page shows two stack panels with radio buttons in them. I want to have it so that the visibility of the second stack panel is dependent on whether certain radio buttons are selected or not.

<Grid Background="#F8FBFD">
    <StackPanel x:Name="StackType" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,93,0,428">
        <materialDesign:Card Padding="32" Margin="16">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Type</TextBlock>
                <RadioButton Checked="NewMode_Checked" Content="New " x:Name="rbtnNew" GroupName="InstallType" IsChecked="{Binding newMode, Mode=TwoWay, Source={StaticResource modes}}"/>
                <RadioButton  Checked="UpgradeMode_Checked" Content="Update" x:Name="rbtnUpgrade" GroupName="InstallType" IsChecked="{Binding upgradeMode, Mode=TwoWay, Source={StaticResource modes}}" />
                <RadioButton  Checked="ChangeMode_Checked" Content="Change" x:Name="rbtnChange" GroupName="InstallType" IsChecked="{Binding changeMode, Mode=TwoWay, Source={StaticResource modes}}" />
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
    <StackPanel x:Name="StackMode" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" Visibility="Visible">
        <materialDesign:Card Padding="32" Margin="16" Width="204" Height="147">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Mode</TextBlock>
                <RadioButton Content="Default Settings" Name="rbtnDefaultMode" IsChecked="{Binding defaultMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="defaultSettings_Checked"/>
                <RadioButton Content="Custom Settings" Name="rbtnCustomMode" IsChecked="{Binding customMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="customSettings_Checked"/>
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
</Grid>

In this, I want to have it in a way so that if rbtnNew or rbtnUpgrade are selected, only then should the StackMode panel be should be visible. And if rbtnChange is selected, the panel StackMode panel should stay hidden.

CodePudding user response:

You can add a custom style with a DataTrigger:

  • Remove the Visibility="Visible" from the StackMode panel.
  • Add a Setter that sets the default value of Visibility of the StackPanel to Visible.
  • Add a DataTrigger that sets its value to Collapsed (or Hidden) if the IsChecked value of rbtnChange is true. You can refer to the element with ElementName in the binding.
<Grid Background="#F8FBFD">
    <StackPanel x:Name="StackType" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,93,0,428">
        <materialDesign:Card Padding="32" Margin="16">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Type</TextBlock>
                <RadioButton Checked="NewMode_Checked" Content="New " x:Name="rbtnNew" GroupName="InstallType" IsChecked="{Binding newMode, Mode=TwoWay, Source={StaticResource modes}}"/>
                <RadioButton  Checked="UpgradeMode_Checked" Content="Update" x:Name="rbtnUpgrade" GroupName="InstallType" IsChecked="{Binding upgradeMode, Mode=TwoWay, Source={StaticResource modes}}" />
                <RadioButton  Checked="ChangeMode_Checked" Content="Change" x:Name="rbtnChange" GroupName="InstallType" IsChecked="{Binding changeMode, Mode=TwoWay, Source={StaticResource modes}}" />
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
    <StackPanel x:Name="StackMode" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
        <materialDesign:Card Padding="32" Margin="16" Width="204" Height="147">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Mode</TextBlock>
                <RadioButton Content="Default Settings" Name="rbtnDefaultMode" IsChecked="{Binding defaultMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="defaultSettings_Checked"/>
                <RadioButton Content="Custom Settings" Name="rbtnCustomMode" IsChecked="{Binding customMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="customSettings_Checked"/>
            </StackPanel>
        </materialDesign:Card>
        <StackPanel.Style>
           <Style TargetType="{x:Type StackPanel}">
              <Setter Property="Visibility" Value="Visible"/>
              <Style.Triggers>
                 <DataTrigger Binding="{Binding IsChecked, ElementName=rbtnChange}" Value="True">
                    <Setter Property="Visibility" Value="Collapsed"/>
                 </DataTrigger>
              </Style.Triggers>
           </Style>
        </StackPanel.Style>
    </StackPanel>
</Grid>

Another option is to use the built-in BooleanToVisibilityConverter converter.

<Grid Background="#F8FBFD">
    <Grid.Resources>
       <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Grid.Resources>
    <StackPanel x:Name="StackType" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,93,0,428">
        <materialDesign:Card Padding="32" Margin="16">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Type</TextBlock>
                <RadioButton Checked="NewMode_Checked" Content="New " x:Name="rbtnNew" GroupName="InstallType" IsChecked="{Binding newMode, Mode=TwoWay, Source={StaticResource modes}}"/>
                <RadioButton  Checked="UpgradeMode_Checked" Content="Update" x:Name="rbtnUpgrade" GroupName="InstallType" IsChecked="{Binding upgradeMode, Mode=TwoWay, Source={StaticResource modes}}" />
                <RadioButton  Checked="ChangeMode_Checked" Content="Change" x:Name="rbtnChange" GroupName="InstallType" IsChecked="{Binding changeMode, Mode=TwoWay, Source={StaticResource modes}}" />
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
    <StackPanel x:Name="StackMode" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" Visibility="{Binding IsChecked, ElementName=rbtnChange, Converter={StaticResource BooleanToVisibilityConverter}}">
        <materialDesign:Card Padding="32" Margin="16" Width="204" Height="147">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Mode</TextBlock>
                <RadioButton Content="Default Settings" Name="rbtnDefaultMode" IsChecked="{Binding defaultMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="defaultSettings_Checked"/>
                <RadioButton Content="Custom Settings" Name="rbtnCustomMode" IsChecked="{Binding customMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="customSettings_Checked"/>
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
</Grid>

Update for your comment about the initial state that should be Collapsed. You can just add another DataTrigger for the IsChecked="False" state of the rbtnChange RadioButton.

<Style TargetType="{x:Type StackPanel}">
   <Setter Property="Visibility" Value="Visible"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding IsChecked, ElementName=rbtnChange}" Value="False">
         <Setter Property="Visibility" Value="Collapsed"/>
      </DataTrigger>
      <DataTrigger Binding="{Binding IsChecked, ElementName=rbtnChange}" Value="True">
         <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

Of course, you could also "invert" the style, setting Collapsed as default and adding triggers for each of the other RadioButtons to set Visible, but for more buttons this would not scale well.

  • Related