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 theStackMode
panel. - Add a
Setter
that sets the default value ofVisibility
of theStackPanel
toVisible
. - Add a
DataTrigger
that sets its value toCollapsed
(orHidden
) if theIsChecked
value ofrbtnChange
istrue
. You can refer to the element withElementName
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 RadioButton
s to set Visible
, but for more buttons this would not scale well.